/* Bitmap Header Definition */
typedef struct tagBITMAP
{
LONG bmType;
LONG bmWidth;
LONG bmHeight;
LONG bmWidthBytes;//本文说明此参数的计算方法
WORD bmPlanes;
WORD bmBitsPixel;
LPVOID bmBits;
} BITMAP, *PBITMAP, NEAR *NPBITMAP, FAR *LPBITMAP;
//typedef struct tagBITMAP 中的各个数据类型是什么意思
typedef struct tagBITMAP {
LONG bmType; //必需为0
LONG bmWidth; //位图的宽度(以像素为单位)
LONG bmHeight; //位图的高度(以像素为单位)
/*指定每条光栅所占字节数。此值必须取偶数,
因为图形设备接口(GDI)默认为一个位图的位值组成一个2字节的整数数组。*/
LONG bmWidthBytes;
WORD bmPlanes; // 位图调色板颜色数
WORD bmBitsPixel; // 一个点在每个调色板上接近的颜色位数
LPVOID bmBits; // 指向存储像素阵列的数组
} BITMAP;
bmWidthBytes:
BitMap结构中的bmWidthBytes总算搞懂了,其实很简单:一行像素所占的字节数,一行像素的存储必须按word对齐,所以该值必须为2的倍数。所以计算方式中应体现出向字对齐来,即以16位为一划分。bmWidthBytes=((bitsPerLine+15)/16)*2,其中bitsPerLine=bmWidth*bmBitsPixel。一切搞定。
这是网上的一句话。Specifies the number of bytes in each scan line. This value must be divisible by 2, because the system assumes that the bit values of a bitmap form an array that is word aligned.
Programming Windows里总算找到了个错误,设置bmWidthBytes错误导致无法建立位图,导致程序整个几乎完全失败。以下是错误代码:
HBITMAP StretchBitmap (HBITMAP hBitmap1)
{
BITMAP bm1, bm2 ;
HBITMAP hBitmap2 ;
HDC hdc, hdcMem1, hdcMem2 ;
int cxChar, cyChar ;
// Get the width and height of a system font character
cxChar = LOWORD (GetDialogBaseUnits ()) ;
cyChar = HIWORD (GetDialogBaseUnits ()) ;
// Create 2 memory DCs compatible with the display
hdc = CreateIC (TEXT ("DISPLAY"), NULL, NULL, NULL) ;
hdcMem1 = CreateCompatibleDC (hdc) ;
hdcMem2 = CreateCompatibleDC (hdc) ;
DeleteDC (hdc) ;
// Get the dimensions of the bitmap to be stretched
GetObject (hBitmap1, sizeof (BITMAP), (PTSTR) &bm1) ;
// Scale these dimensions based on the system font size
bm2 = bm1 ;
bm2.bmWidth = (cxChar * bm2.bmWidth) / 4 ;
bm2.bmHeight = (cyChar * bm2.bmHeight) / 8 ;
bm2.bmWidthBytes = ((bm2.bmWidth+15)/16)*2 ;
~~~~~~~~~~~~~~~~少了*bm2.bmBitsPixel
// Create a new bitmap of larger size
hBitmap2 = CreateBitmapIndirect (&bm2) ;
// Select the bitmaps in the memory DCs and do a StretchBlt
SelectObject (hdcMem1, hBitmap1) ;
SelectObject (hdcMem2, hBitmap2) ;
StretchBlt (hdcMem2, 0, 0, bm2.bmWidth, bm2.bmHeight,
hdcMem1, 0, 0, bm1.bmWidth, bm1.bmHeight, SRCCOPY) ;
// Clean up
DeleteDC (hdcMem1) ;
DeleteDC (hdcMem2) ;
DeleteObject (hBitmap1) ;
return hBitmap2 ;
}
来自:http://www.blog.edu.cn/user2/29800/archives/2006/1328638.shtml