windows程序设计关于BITMAP的一些小疑问

Guy_Fwakes 2015-02-08 10:08:22
以下是第14章中GRAFMENU中的一个子函数,作用是调整载入图片的大小

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 ;

// 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 ;
}



下面是我不太明白的三句代码:
bm2.bmWidth = (cxChar * bm2.bmWidth) / 4 ;
bm2.bmHeight = (cyChar * bm2.bmHeight) / 8 ;
bm2.bmWidthBytes = ((bm2.bmWidth + 15) / 16) * 2 ;
前两句使用字体的宽度和高度分别乘以原来图片的宽度和高度然后除以一个数,有什么实际的意义吗?
最后一句改变的“一行像素所占的字节数”为什么+15又/16和*2(程序使用的图片为黑白双色的图片)


希望知道的大神能解惑一下,万分感激
...全文
83 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
信阳毛尖 2015-02-09
  • 打赏
  • 举报
回复
怎么说呢,这里面牵扯到几个概念: 1、对话基本单位(包括水平基本单位、垂直基本单位,GetDialogBaseUnits函数返回的水平基本单位同系统字体中字符以像素为单位的平均宽度相等;垂直基本单位同系统字体中字符的以像素为单位的平均高度相等) 2、对话框模板(简单的理解就是一个描述对话框的内存结构) 3、对话框模板单位(包括水平对话框模板单位、垂直对话框模板单位) 4、每一个水平基本单位同四个水平对话框模板单位相等;每一个垂直基本单位同八个垂直对话框模板单位相等 因此 bm2.bmWidth = (cxChar * bm2.bmWidth) / 4 ; bm2.bmHeight = (cyChar * bm2.bmHeight) / 8 ; 这两句的意思就是把对话框模板单位转换为像素(位图的宽高以像素为单位) 关于 bm2.bmWidthBytes = ((bm2.bmWidth + 15) / 16) * 2 ;这句,因为要牵扯到bmWidthBytes的含义: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(每一行像素所在的byte数。此值必须取偶数, 因为图形设备接口(GDI)默认为一个位图的位值组成一个2字节的整数数组) 其中(bm2.bmWidth + 15) / 16 的意思就是向WORD(2字节,16位)对齐(字节对齐),以16位为一划分 PS:个人以为,在Windows C++编程中这部分用到的很少,建议LZ了解一下即可
副组长 2015-02-09
  • 打赏
  • 举报
回复
最后一行是为了保证每行像元所占字节数能被4整除。这是BITMAP要求的。 我觉得这不是一个什么好规定,还有BMP数据上下颠倒存放,估计是早期就这么设计了,现在没法改。

16,371

社区成员

发帖
与我相关
我的任务
社区描述
VC/MFC相关问题讨论
社区管理员
  • 基础类社区
  • Web++
  • encoderlee
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告

        VC/MFC社区版块或许是CSDN最“古老”的版块了,记忆之中,与CSDN的年龄几乎差不多。随着时间的推移,MFC技术渐渐的偏离了开发主流,若干年之后的今天,当我们面对着微软的这个经典之笔,内心充满着敬意,那些曾经的记忆,可以说代表着二十年前曾经的辉煌……
        向经典致敬,或许是老一代程序员内心里面难以释怀的感受。互联网大行其道的今天,我们期待着MFC技术能够恢复其曾经的辉煌,或许这个期待会永远成为一种“梦想”,或许一切皆有可能……
        我们希望这个版块可以很好的适配Web时代,期待更好的互联网技术能够使得MFC技术框架得以重现活力,……

试试用AI创作助手写篇文章吧