Hàm này sẽ load ảnh lên vị trí x,y
void load(char*filename,int x=0,int y=0)
{
int o;
long size=0,h=0,w=0,bit=0,offset=0,ww=0;
FILE *ptr=NULL;
//Mở file ở chế độ nhị phân
ptr=fopen(filename,"rb");
if(!ptr)
{
cout<<"khong mo duoc tep";
system("pause");
return ;
}
/*
Nhảy con trỏ tập tin đến vị trí 0x12 (số hex). Ở đây chứa giá trị width của ảnh là một số nguyên 4 byte (32 bit). mõi lần chúng ta đọc 1 byte (8 bit). Nên cần phải đọc 4 lần kết hợp với phép dịch bit để có được giá trị của width.
*/
fseek(ptr,0x12,SEEK_SET);
o=fgetc(ptr);
w+=long(o);
o=fgetc(ptr);
w+=long(o)<<8;
o=fgetc(ptr);
w+=long(o)<<16;
o=fgetc(ptr);
w+=long(o)<<24;
// giống như ở trên nhưng lần này ta đọc thông số height
fseek(ptr,0x16,SEEK_SET);
o=fgetc(ptr);
h+=long(o);
o=fgetc(ptr);
h+=long(o)<<8;
o=fgetc(ptr);
h+=long(o)<<16;
o=fgetc(ptr);
h+=long(o)<<24;
/*
chúng ta đọc vào số bit cần mã hóa 1 pixel, ở đây phải là 4 vì ảnh này có 16 màu.
đối với các trường hợp khác là:
2 màu - 1bit
4 màu - 2bit
16 màu - 4 bit
256màu - 8bit
65535 màu - 16bit
16777216 màu - 24bit
giá trị này là số nguyên 2 byte nên ta đọc 2 lần, mõi lần 1 byte
*/
fseek(ptr,0x1C,SEEK_SET);
o=fgetc(ptr);
bit+=int(o);
o=fgetc(ptr);
bit+=int(o)<<8;
//kiểm tra nếu không phải ảnh 16 màu thì thông báo lỗi và thoát
if(bit!=4)
{
cout<<"File nay khong phai o che do 16 mau";
system("pause");
return ;
}
//Đọc vào vị trí bắt đầu của vùng chứa dữ liệu ảnh, giá trị này là 118 đối với ảnh 16 màu.
// đây cũng là số nguyên 4 byte.
fseek(ptr,0x0A,SEEK_SET);
o=fgetc(ptr);
offset+=long(o);
o=fgetc(ptr);
offset+=long(o)<<8;
o=fgetc(ptr);
offset+=long(o)<<16;
o=fgetc(ptr);
offset+=long(o)<<24;
/*
Các bạn chịu khó đọc tiếng anh. mình hiểu nhưng không thể dịch lại cho rõ nghĩa được
The bits representing the bitmap pixels are packed in rows. The size of each row is rounded up to a multiple of 4 bytes (a 32-bit DWORD) by padding.
For images with Height > 1, multiple padded rows are stored consecutively, forming a Pixel Array.
The total number of bytes necessary to store one row of pixels can be calculated as: CEILING( ImageWidth * BitsPerPixel / 32 ) * 4
*/
ww=(bit*w)*4/32;
fseek(ptr,offset,SEEK_SET); //nhảy đến vùng chứa dữ liệu ảnh.
/*
dùng 2 vòng lập for để duyệt các qua các pixel. vì 1 pixel chỉ cần 4bit nên mõi lần ta đọc 1 byte tức là duyệt qua 2 pixel, dùng phép dịch bit và phép & để tách ra 2 giá trị 4bit trong 1byte.
*/
int i,j,a,b;
for(i=0;i<h;i++)
for(j=0;j<ww;j++)
{
o=fgetc(ptr);
a=o>>4; //lấy 4bit đầu đưa vào a
b=o&(0x0f); //lấy 4bit sau đưa vào b
putpixel(j*2+x,(h-1-i)+y,getcol(a)); //cộng vào 2 giá trị xy để in ảnh ở vị trí mong muốn.
if(j*2+1<w)
putpixel(j*2+1+x,(h-1-i)+y,getcol(b)); //hàm getcol chuyển giá trị màu lưu trong tập tin BMP thành các giá trị màu
// tương ứng trong DEV C
}
fclose(ptr);
}
int getcol(int col)
{
switch(col)
{
case 0: return BLACK; //BLACK;
case 1: return RED; //RED;
case 2: return GREEN; //GREEN
case 3: return BROWN; //BROWN
case 4: return BLUE; //BLUE;
case 5: return MAGENTA; //MAGENTA;
case 6: return CYAN; //CYAN;
case 7: return LIGHTGRAY; //LIGHTGRAY;
case 8: return DARKGRAY; //DARKGRAY;
case 9: return LIGHTRED; //LIGHTRED;
case 10:return LIGHTGREEN; //LIGHTGREEN
case 11:return YELLOW; //YELLOW;
case 12:return LIGHTBLUE; //LIGHTBLUE;
case 13:return LIGHTMAGENTA; //LIGHTMAGENTA
case 14:return LIGHTCYAN; //LIGHTCYAN;
case 15:return WHITE; //WHITE;
}
return col;
}
Ở đây ta chỉ đọc những thông số cần thiết cho việc load ảnh 16 màu, còn rất nhiều thông số trong file bmp các bạn vào trang web
[You must be registered and logged in to see this link.] để tìm hiểu thêm.