والا گوگل چیز خوبیه ....
اول اینو ببین http://en.wikipedia.org/wiki/BMP_file_format
Fig. 2 Structure of BMP file پس از جدول بالا می فهمیم که در 14 بایت اول فایل اطلاعات هدر (سر فایل) قرار داره که آخریش به کار می آد (آفست) که در واقع برای ما مشخص می کنه که اطلاعات خام بیتی از کجای فایل شروع می شود در 40 بایت بعدی اطلاعات برچسب ها که برای ما مهم هستند قرار داره
اولی سایز این بر چسب ها رو مشخص می کنه یعنی همین 40 بایت که داریم می خونیم ممکنه بیشتر هم باشه که از اینجا می فهمیم چقدره
بعدش عرض این عکسی که می خواهیم به نمایش بزاریم مشخص می شود و سپس طول و بعد از طول سطح ها یا بعد ها که باید روی 1 تنظیم باشه چون ما می خواهیم عکس مسطح نمایش بدیم و بعدش بیت کانت هست که خلی خیلی برای نمایش عکس مهم هست و عمق رنگ ها رو به ما نشون میده که می تونه مقادیر 1و4و8و16و24و32 رو داشته باشه و اگه 2 را به توان این اعداد برسونید تعداد رنگ های مختلفی که یک پیکسل می تونه نمایش بده مشخص میشه و این قسمت به ما میگه که اولا چقدر حافظه لازمه بعد در هر ÷یکسل باید چند بیت قرار بگیره مثلا اگر تصویر ما 8 بیتی باشه می شه با 1 بایت هر پیکسل رو مشخص کد و اگر ضرب در طول و عرض تصویر بشود حافظه لازم برای نمایش این عکس مشخص می شود
و برچسب بعدی هم خیلی مهم است که نوع فشرده سازی به کار رفته در این عکس را برای ما مشخص می کنه:
0 برای حالت ساده است بدون فشرده سازی و 1 برای حال 8 بیت بر پیکسل با نوع RLE فشرده سازی 2 برای 16 بیت بر پیکسل با نوع RLE فشرده سازی 3 برای 24 و 32 بیت بر پیکسل با نوع فشرده سازی Bit field و 4 فشرده سازی از نوع jpeg و 5 برای فشرده سازی png که البته اگر غیر یک بود ما بیخیال نمایشش می شویم
مقدار بعدی هم مربوط به سایز قبل از فشردگی فایل است که اگر فشرده نباشه باید روی 0 قرار بگیره
و قسمت بعدی مربوط می شه به وضوح تصویر یعنی چند تا پیکسل رو در1 متر در عرض (افقی) نمایش باید داد که هرچقدر بزرگتر باشه کیفیت عکس بیشتره و قسمت بعدی همین در طول (عمودی) هست.
قسمت بعدی مربوط به تعداد رنگها برای هر پیکسل است که به طور پیشفرض 0 که با همون 2 به توان بیت ها حساب میشه
قسمت بعدی هم مربوط به رنگ های مهم تره که بطور پیشفرض 0 قرار داده میشه وکلا این را در نظر نمی گیریم.
خوب قسمت بعدی هم ماله مقدار های کمتر از 8 بیت بر پیکسل هست که چون بیشتر فایل ها الان 24 و23 بیت بر پیکسل هستند پس این قسمت رو هم در نظر نمی گیریم.
ادامه دارد ........
حتما به ویکی پدیا سر بزنید خیلی قشنگ تر توضیح داده البته این کار یک کار سطح پایین هست برای درک مراحل کار
نکته فایل های بیتمپ یکی از ساده ترین نوع فایل های گرافیکی هستند پس فکر نکنید اینها خیلی بدرد بخور هستند در ضمن یک نکته که وجود داره اینه که ترتیب پیکسل ها از گوشه پایین سمت چپ شروع میشه یعنی اگر فایل را از اولش بخونیم وبنویسیم یک عکس وارونه مشاهده می شود ..............
رفع ابهام :
روش نمایش این عکس شبیه به نمایش یک آرایه دوبعدی است کار خاصی انجام نمی دهیم دو تا حلقه که یکی به اندازه طول ودیگری به اندازه پهنای تصویر باشه کافیه و یک تابع که رنگ هر پیکسل را مشخص کنه برای رنگ وقتی ما اطلاعات خام بیتی را می خونیم که بر اساس هگزدسیمال هست می تونیم دو تا کار انجام دهیم اول اینکه اونها رو تبدیل به دسیما کنیم وبا تابع putpixel سر فایل گرافیک پیکسل را رسم کنیم یا اینکه در 1 بایت یک بایت بخونیم و با تابع vga پیکسل را رسم کنیم اینطوری:
for(y=0;y<64;y++)
for(x=0;x<32;x++)
VGA [x+y*320]=bitmap [x+y*32];
در ضمن توضیحات بالا رو باید با جدول مرور کنید....
قسمت دوم:
خوب در ادامه طراحی یک برانامه برای نمایش عکس های نوع بیتمپ فهمیدیم که این عکس ها چندین نوع هستند که 1 و4و8و14و24و32 بیت بر پیکسل انواع آن هستند که اگر بخواهیم یک کد جامع برای نمایش بیت مپ بنویسیم باید همه این نوع ها که خودشون رو در سر فایل معرفی می کنند را تفکیک کنیم و فرمت های فشرده را هم در نظر بگیریم . که در بالا یک سورس کامل لینک شد ولی
یک مطلب دیگه که وجود داره این هست که در نوع های 1 و4 و8 بیتی بعد از هدر اینفو تازه باید پالت های رنگ رو ترجمه کنیم که خودش یک کار وقت گیر هست که گفتیم در نوع 24 و 32 بیت این قسمت کامل حذف شده است و احتیاجی به ترجمه رنگ پالت ها نیست . حالا ما می خواهیم تحت توربو سی یک برنامه خیلی خیلی ساده برای نمایش نوع 8 بیتی بنویسیم دلیل انتخاب این نوع, محدودیت رنگ در داس ,16 رنگ مجزا و اینکه چون هر کارکتر 8 بیت هست یعنی یک بایت می تونه هر پیکسل را ذخیره کنه .
گفتیم که برای این کار میشه از دوتا حلقه ساده استفاده کرد و مثل نمایش یک ماتریس پیکسل ها را در کنار هم گذاشت تا شکل ما مشخص شود و گفتیم که باید اولین پیکسل که در فایل خوانده می شود اولین پیکسل گوشه پایین سمت چپ عکس را تشکیل می دهد اما اصل مطلب:
اول باید سر فایل ها رو بخونیم که قبلا راجع به اون توضیح دادم که سه تا کلاس تعریف می کنیم اولی برای تشخیص هویت فایل
دومی اطلاعات اصلی
سومی اطلاعات عمومی فایل بیت مپ
خوب تمام این کلاس ها در سایت ویکی پدیا وجود داره که می تونید ازشون استفاده کنید چیز هایی که ما لازم داریم طول و عرض عکس و (آفست) آدرس جایی که اطلاعات پیکسل ها ذخیره شده است و نوع بیتمپ که اگر غیر از 8 بود یک اخطار بدیم که فایل رو نمی تونیم تر جمه کنیم خوب بیشتر قسمت ها در کد توضیح داده شده:
#include <iostream.h>
#include <graphics.h>
#include <fstream.h>
#include <conio.h>
#include <stdlib.h>
#include <dos.h>
#include <stdio.h>
struct U{
unsigned char magic[2];
}mag;
struct master {
// word bftype;
unsigned long Size;
unsigned short Reserved;
unsigned short Reserved2;
unsigned long BitsOffset;
} HEADER;
class info {public:
unsigned long header_sz;
unsigned long width;
unsigned long height;
unsigned short nplanes;
unsigned short bitspp;
unsigned long compress_type;
unsigned long bmp_bytesz;
unsigned long hres;
unsigned long vres;
unsigned long ncolors;
// unsigned long nimpcolors;
} INFOHEADER;
huge DetectSvga()
{
return 2;
}
void Show(char* filename,int xcor,int ycor)
{
fstream File;
File.open(filename,ios::in);
char Ch;
File.read((char*)&mag,2);// read te 2 frist byte for know file
/*if (mag.magic!="BM"){
printf("file not a bitmap");
exit(0);
}*/
File.read((char*)&HEADER,12); //read for get offst bye of bitmap data
File.read((char*)&INFOHEADER,40); //read for width , heght and know 8 bit
unsigned int i;
File.seekg(HEADER.BitsOffset);
for(i=0;i<INFOHEADER.height;i++) //This for loop is used to display the bitmap.
{
for(int j=0;j<INFOHEADER.width;j++)
{
File.read(&Ch,1); // Here Ch reads the color of your bitmap.
putpixel(xcor+j,ycor+INFOHEADER.height-i,Ch);//write pixel to screen
}
}
File.close();
}
void main()
{
clrscr();
int gd = DETECT, md, a;
initgraph(&gd,&md,"..\\bgi");
installuserdriver("svga256",&DetectSvga);
char msg[15];
char* k;
cout<<"plz write adress of 8-bit bitmap format file: (example: c:/test.bmp)"<<endl;
cin>>k;
Show(k,100,100);
getch();
}