Có bạn nào biết cách ghi file bitmap không nhỉ.Mình chụp hình desktop rồi,tính ghi ra file nhưng chả biết làm sao cả,sử dụng các hàm ghi nhị phân trong C++ thì sao không được gì cả (mình đang lập trình với API).Mong được các cao thủ giúp đỡ
Có bạn nào biết cách ghi file bitmap không nhỉ.Mình chụp hình desktop rồi,tính ghi ra file nhưng chả biết làm sao cả,sử dụng các hàm ghi nhị phân trong C++ thì sao không được gì cả (mình đang lập trình với API).Mong được các cao thủ giúp đỡ
Thực thế thì có rât nhiều hàm hỗ trợ load file BMP nên mình cũng chưa ghi thử file BMP bao giờ. Nhưng file TGA thì có làm vài lần rồi và có lẽ nó cũng tương tự.
Mình vừa tham khảo MSDN xong.
BITMAPFILEHEADER fileHeader;
BITMAPINFOHEADER infoHeader;
fileHeader.bfType = 0x4D42; // Danh dau kieu BITMAP
fileHeader.bfSize = 0; // Khong su dung
fileHeader.bfReserved1 = 0;
fileHeader.bfReserved2 = 0;
fileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
infoHeader.biSize = sizeof(infoHeader);
infoHeader.biWidth = bitmap_dx; // Chiều rộng pixel
infoHeader.biHeight = bitmap_dy; // Chiều cao pixel
infoHeader.biPlanes = 1; // Mặc định là
infoHeader.biBitCount = 24; // Số bit/pixel 8 - 16 - 32 ...
infoHeader.biCompression = BI_RGB; // Không nén ...
infoHeader.biSizeImage = 0;
infoHeader.biXPelsPerMeter = 0;
infoHeader.biYPelsPerMeter = 0;
infoHeader.biClrUsed = 0;
infoHeader.biClrImportant = 0;
file.write((char*)&fileHeader, sizeof(fileHeader));
file.write((char*)&infoHeader, sizeof(infoHeader));
Ứng với mỗi INFOHEADER (phụ thuộc vào biBitCount, iCompression)thì có một cách tổ chức dữ liệu trên DATA riêng.
Đơn giản nhât là trường hợp trên thì mỗi pixel sẽ là 24bit (3 byte thể hiện màu R G B).
Như vậy ta có cách tổ chức 1 pixel, có thể trật tự R,G,B khác mình không nhớ rõ lắm. Nếu thấy sai màu thì đảo lại là R,G,B hay B,G,R chẳng hạn
typedef struct tagPixel{
unsigned char B;
unsigned char G;
unsigned char R;
}COLOR;
Nếu 32bit per Pixel
typedef struct tagPIXEL{
unsigned char B;
unsigned char G;
unsigned char R;
unsigned char Chuasd;
}COLOR;
Còn 16 Bit và 8 bit thì có thể dùng kiểu dữ liệu "int" hay "unsigner char"
COLOR palette[255];
palette là các bảng màu được sử dụng trong file BITMAP.
unsigned char aData;
aData = new PIXEL[bitmap_dx*bitmap_dy];
for (int x = 0 ;i< bitmap_dx;i++){
for (int y = 0 ;i< bitmap_dy;i++){
aData[x*y] = index; // Chỉ mục lên bảng màu palette --> Màu thứ index
}
}
file.write(palette, sizeof(COLOR)*255);
file.write(aData,bitmap_dx*bitmap_dy);
Mình không dám tự tin là CODE chạy đúng, dĩ nhiên bạn phải tham khảo nhiều, mình đang o phòng NET nên ko có thời gian.
Hy vọng sẽ giúp bạn chút ít!
Được sửa bởi eXecutive lúc 14:05 ngày 23-06-2007
Tham số truyền vào là hBitmap (handle của file bitmap) và char * (tên file)
LPVOID pBuf; //bitmap data buffer
HDC hdc = GetDC(NULL); //DC giữ bitmap
BITMAPINFO bmpInfo = {0}; //Thông tin Bitmap
BITMAPFILEHEADER bmpFileHeader = {0};
//khai báo thành phần header
bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
//lấy thông tin Bitmap
GetDIBits(hdc, hBitmap, 0, 0, 0, &bmpInfo, DIB_RGB_COLORS);
//Thông báo kích thước Bitmap
bmpInfo.bmiHeader.biSizeImage =
bmpInfo.bmiHeader.biWidth* bmpInfo.bmiHeader.biHeight*4;
//cấp phát bộ nhớ để chứa Bitmap data
pBuf = malloc(bmpInfo.bmiHeader.biSizeImage);
//Chép các bit vào buffer
GetDIBits(hdc, hBitmap, 0, bmpInfo.bmiHeader.biHeight,
pBuf, &bmpInfo,DIB_RGB_COLORS);
//kích thước file
bmpFileHeader.bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + bmpInfo.bmiHeader.biSizeImage;
//Offset byte đầu tiên Bitmap bits
bmpFileHeader.bfOffBits = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER);
bmpFileHeader.bfType = 'MB';
FILE *f = fopen(strFileName, “wb”);
fwrite(&bmpFileHeader,sizeof(BITMAPFILEHEADER),1,f );
fwrite(&bmpInfo.bmiHeader,sizeof(BITMAPINFOHEADER) ,1,f);
fwrite(pBuf,bmpInfo.bmiHeader.biSizeImage,1,f);
fclose(f);
Chúc bạn thành công
Thanks các bạn,nhưng có một điều là khi mình khai báo thư viện <fstream.h> thì nó báo lỗi,do đó không thể dùng fwrite được (mình viết trên VC++.NET trong Visual studio 2005).
Mình ko hiểu nó bị lỗi gì cả,có cách nào khắc phục không các bạn
PS : khi viết chương trình bình thường non-API thì ko sao,nhưng khi viết với API thì mới có lỗi trên
nó báo lỗi ji`. Bạn ghi rõ ra chút nha!Chứ theo MSDN thì hàm fwrite thì có liên quan gì đến thư viện fstream đâu bạn.
Có phải là lỗi "No such file or directory" hông bạn ?? Bạn thử include như vậy thử xem #include<fstream> .
Àh mấy bạn chuyển mớ mã đó sang MFC được ko, mình đã từng đọc 1 source code chụp ảnh màn hình nhưng lại ko hiểu lúc save bức ảnh lại(hầu như là ko có luôn,nó chỉ nói định dạng bức ảnh lúc save lại thôi) .
Bookmarks