/* 功能: 創建一幅24位真彩色位圖
** 作者: mayadong7349
** 參考: MSDN(Visual Studio 2005)、(百度百科:bmp) http://baike.baidu.com/view/7671.htm#2
*/
#include <windows.h>
#include <stdio.h>
#include <stdlib.h>
#define BMP_W 640L
#define BMP_H 480L
void SetBmpInfoHeader(PBITMAPINFOHEADER pbmpih)
{
/* 14~17: 本結構體所佔字節數, 固定值40
MSDN: Specifies the number of bytes required by the structure.
*/
pbmpih->biSize = 40;
/* 18~21: 位圖的寬度(以像素pixel爲單位)
MSDN: Specifies the width of the bitmap, in pixels.
Windows 98/Me, Windows 2000/XP: If biCompression is BI_JPEG or BI_PNG, the biWidth member specifies
the width of the decompressed JPEG or PNG image file, respectively.
*/
pbmpih->biWidth = BMP_W;
/* 22~25: 位圖的高度
MSDN: Specifies the height of the bitmap, in pixels. If biHeight is positive, the bitmap is a
bottom-up DIB and its origin is the lower-left corner. If biHeight is negative, the bitmap is
a top-down DIB and its origin is the upper-left corner.
If biHeight is negative, indicating a top-down DIB, biCompression must be either BI_RGB or
BI_BITFIELDS. Top-down DIBs cannot be compressed.
Windows 98/Me, Windows 2000/XP: If biCompression is BI_JPEG or BI_PNG, the biHeight member specifies
the height of the decompressed JPEG or PNG image file, respectively.
*/
pbmpih->biHeight = BMP_H;
/* 26~27: 目標設備的級別, 固定值:1
MSDN: Specifies the number of planes for the target device. This value must be set to 1*/
pbmpih->biPlanes = 1;
/* 28~29: 一個像素所佔bit數, 可以是:1(雙色)、4(16色)、8(256色)
、16(65536色)、24(真彩色2^24種顏色)、32(真彩色2^32種顏色),具體參閱MSDN。
對於24位真彩色位圖, 一個像素佔用三個字節,即24 bits
MSDN: Specifies the number of bits-per-pixel. The biBitCount member of the BITMAPINFOHEADER
structure determines the number of bits that define each pixel and the maximum number
of colors in the bitmap. This member must be one of the following values.
0: Windows 98/Me, Windows 2000/XP: The number of bits-per-pixel is specified or is implied
by the JPEG or PNG format.
1: The bitmap is monochrome, and the bmiColors member of BITMAPINFO contains two entries.
Each bit in the bitmap array represents a pixel. If the bit is clear, the pixel is displayed
with the color of the first entry in the bmiColors table; if the bit is set, the pixel has
the color of the second entry in the table.
4: The bitmap has a maximum of 16 colors, and the bmiColors member of BITMAPINFO contains up to
16 entries. Each pixel in the bitmap is represented by a 4-bit index into the color table.
For example, if the first byte in the bitmap is 0x1F, the byte represents two pixels.
The first pixel contains the color in the second table entry, and the second pixel contains
the color in the sixteenth table entry.
8: The bitmap has a maximum of 256 colors, and the bmiColors member of BITMAPINFO contains up
to 256 entries. In this case, each byte in the array represents a single pixel.
16: The bitmap has a maximum of 2^16 colors. If the biCompression member of the BITMAPINFOHEADER
is BI_RGB, the bmiColors member of BITMAPINFO is NULL. Each WORD in the bitmap array represents
a single pixel. The relative intensities of red, green, and blue are represented with five bits for
each color component. The value for blue is in the least significant five bits, followed by five
bits each for green and red. The most significant bit is not used. The bmiColors color table is
used for optimizing colors used on palette-based devices, and must contain the number of entries
specified by the biClrUsed member of the BITMAPINFOHEADER.
If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member contains
three DWORD color masks that specify the red, green, and blue components, respectively,
of each pixel. Each WORD in the bitmap array represents a single pixel.
Windows NT/Windows 2000/XP: When the biCompression member is BI_BITFIELDS, bits set in each DWORD
mask must be contiguous and should not overlap the bits of another mask.
All the bits in the pixel do not have to be used.
Windows 95/98/Me: When the biCompression member is BI_BITFIELDS, the system supports only the
following 16bpp color masks: A 5-5-5 16-bit image, where the blue mask is 0x001F,
the green mask is 0x03E0, and the red mask is 0x7C00; and a 5-6-5 16-bit image,
where the blue mask is 0x001F, the green mask is 0x07E0, and the red mask is 0xF800.
24: The bitmap has a maximum of 2^24 colors, and the bmiColors member of BITMAPINFO is NULL.
Each 3-byte triplet in the bitmap array represents the relative intensities of blue, green,
and red, respectively, for a pixel. The bmiColors color table is used for optimizing colors
used on palette-based devices, and must contain the number of entries specified by the biClrUsed
member of the BITMAPINFOHEADER.
32: The bitmap has a maximum of 2^32 colors. If the biCompression member of the BITMAPINFOHEADER is
BI_RGB, the bmiColors member of BITMAPINFO is NULL. Each DWORD in the bitmap array represents
the relative intensities of blue, green, and red, respectively, for a pixel. The high byte in
each DWORD is not used. The bmiColors color table is used for optimizing colors used on
palette-based devices, and must contain the number of entries specified by the biClrUsed member
of the BITMAPINFOHEADER.
If the biCompression member of the BITMAPINFOHEADER is BI_BITFIELDS, the bmiColors member contains
three DWORD color masks that specify the red, green, and blue components, respectively, of each pixel.
Each DWORD in the bitmap array represents a single pixel.
Windows NT/ 2000: When the biCompression member is BI_BITFIELDS, bits set in each DWORD mask must
be contiguous and should not overlap the bits of another mask. All the bits in the
pixel do not need to be used.
Windows 95/98/Me: When the biCompression member is BI_BITFIELDS, the system supports only the following
32-bpp color mask: The blue mask is 0x000000FF, the green mask is 0x0000FF00, and
the red mask is 0x00FF0000.
*/
pbmpih->biBitCount = 24;
/* 30~33:指定是否壓縮, (如果壓縮了)採用的壓縮格式。
可以爲: BI_RGB、BI_RLE4、BI_RLE8、BI_BITFIELDS、BI_PNG、BI_JPEG
有的位圖會進行遊程長度編碼:BI_RLE4、BI_RLE8
壓縮可以節省空間, 但不便於編程讀寫。BI_RGB表示不進行壓縮處理
MSDN: Specifies the type of compression for a compressed bottom-up bitmap
(top-down DIBs cannot be compressed). This member can be one of the following values.
BI_RGB: An uncompressed format.
BI_RLE8: A run-length encoded (RLE) format for bitmaps with 8 bpp. The compression format
is a 2-byte format consisting of a count byte followed by a byte containing a color index.
For more information, see Bitmap Compression.
BI_RLE4: An RLE format for bitmaps with 4 bpp. The compression format is a 2-byte format
consisting of a count byte followed by two word-length color indexes.
For more information, see Bitmap Compression.
BI_BITFIELDS: Specifies that the bitmap is not compressed and that the color table consists
of three DWORD color masks that specify the red, green, and blue components,
respectively, of each pixel. This is valid when used with 16- and 32-bpp bitmaps.
BI_JPEG: Windows 98/Me, Windows 2000/XP: Indicates that the image is a JPEG image.
BI_PNG: Windows 98/Me, Windows 2000/XP: Indicates that the image is a PNG image.
*/
pbmpih->biCompression = BI_RGB;
/* 34~37: 位圖數據區所佔字節數,有固定的計算公式
MSDN: Specifies the size, in bytes, of the image. This may be set to zero for BI_RGB bitmaps.
Windows 98/Me, Windows 2000/XP: If biCompression is BI_JPEG or BI_PNG,
biSizeImage indicates the size of the JPEG or PNG image buffer, respectively.*/
pbmpih->biSizeImage = ((((pbmpih->biWidth * pbmpih->biBitCount) + 31) & ~31) / 8) * pbmpih->biHeight;
/* 38~41: 位圖水平分辨率,每米像素數
MSDN: Specifies the horizontal resolution, in pixels-per-meter,
of the target device for the bitmap. An application can use this value
to select a bitmap from a resource group that best matches the characteristics of the current device. */
pbmpih->biXPelsPerMeter = 0L;
/* 42~45: 位圖垂直分辨率,每米像素數
MSDN: Specifies the vertical resolution, in pixels-per-meter, of the target device for the bitmap.*/
pbmpih->biYPelsPerMeter = 0L;
/* 46~49: 位圖實際使用顏色表中顏色數(對於有調色板的位圖來說實際上是調色板中顏色項數,
24位真彩色位圖不需要調色板, 設爲0, 8位灰度位圖爲256(2^8種顏色)。
MSDN:If this value is zero, the bitmap uses the maximum number of colors corresponding
to the value of the biBitCount member for the compression mode specified by biCompression. */
pbmpih->biClrUsed = 0L;
/* 50~53: 顯示位圖所需顏色數
MSDN: Specifies the number of color indexes that are required for displaying the bitmap.
If this value is zero, all colors are required. */
pbmpih->biClrImportant = 0L;
}
void SetBmpFileHeader(PBITMAPFILEHEADER pbmpfh, const PBITMAPINFOHEADER pbmpih)
{
/* 0~1: 固定值: "BM"(或0x4D42),即表明這是位圖(一般以bmp爲文件名後綴)
MSDN: Specifies the file type, must be BM.
*/
pbmpfh->bfType = *(WORD *)"BM";
/* 2~5: 位圖文件總大小(佔用總字節數, 包括文件頭、信息頭、調色板、位圖數據區佔用字節數)
MSDN: Specifies the size, in bytes, of the bitmap file.
*/
pbmpfh->bfSize = pbmpih->biSizeImage + 54 + pbmpih->biClrUsed * sizeof(RGBQUAD);
/* 6~7: 固定值0: 目前沒什麼用, 可能留作將來擴展。也有的結構體中有這樣的域是爲了內存對齊
MSDN: Reserved; must be zero.
*/
pbmpfh->bfReserved1 = 0;
/* 8~9: 固定值
MSDN: Reserved; must be zero.
*/
pbmpfh->bfReserved2 = 0;
/* 10~13: 位圖數據區起始位置, 計算方法爲:
位圖文件頭14個字節+位圖信息頭40個字節+位圖調色板所佔字節數,
這裏要創建的是一張24位位圖(無調色板),故設置爲54 也可以。
MSDN: Specifies the offset, in bytes, from the beginning of the BITMAPFILEHEADER structure to
the bitmap bits.
*/
pbmpfh->bfOffBits = 54 + pbmpih->biClrUsed * sizeof(RGBQUAD);
}
int main(void)
{
BITMAPFILEHEADER bmpfh = { 0 }; /* 位圖文件頭 */
BITMAPINFOHEADER bmpih = { 0 }; /* 位圖信息頭 */
FILE *fpBmp = NULL;
COLORREF color = RGB(0xf0,0xca,0xa6); /* 天藍色 */
BYTE black = 0;
int fillbits;
int w, h;
SetBmpInfoHeader(&bmpih);
SetBmpFileHeader(&bmpfh, &bmpih);
fillbits = ( 4 - ( bmpih.biWidth * 3 ) % 4 ) % 4;
fpBmp = fopen("D:\\rendering.bmp", "wb");
if (NULL == fpBmp) {
perror("fopen failed:");
system("pause>nul");
exit(EXIT_FAILURE);
}
fwrite(&bmpfh, sizeof(BITMAPFILEHEADER), 1, fpBmp); /* 寫入位圖文件頭 */
fwrite(&bmpih, sizeof(BITMAPINFOHEADER), 1, fpBmp); /* 寫入位圖信息頭 */
/* 寫入調色板(如果有的話) */
/* 寫入位圖數據 */
for (h = 0; h < BMP_H; ++h) {
for (w = 0; w < BMP_W; ++w) {
fwrite(&color, 3, 1, fpBmp); /* 將像素值顏色寫入位圖文件 */
}
/* 邊界填充
對於24位位圖每個像素佔3個字節,且每個掃描行所佔字節數必須是4的倍數。
比如,對於一張寬度爲21個像素的24色位圖, 理論上每掃描行佔用21*3=63個字節,
但63不是4的倍數,所以需要在該掃描行的最後填充一個字節的0,湊到64,
這樣實際上每掃描行佔用64個字節。
fillbits = ( 4 - ( biheader.biWidth * 3 ) % 4 ) % 4; 參考自acepig, 作用是
計算每掃描行需要填充幾個字節的0。對於寬度是4的倍數的圖片, count爲0。
*/
fwrite(&black, 1, fillbits, fpBmp);
}
fclose(fpBmp);
system("mspaint D:\\rendering.bmp");
return 0;
}
C語言創建24位真彩色位圖
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.