• win32—GrafMenu的CreateBitmapIndirect创建失败的问题


    CBitmap::CreateBitmapIndirect 函数创建位图成功却在CDC::SelectObject 选择位图时却失败,原因是CreateBitmapIndirect不能创建彩色位图,只能创建单色位图,虽然CreateBitmapIndirect创建彩色位图时也能返回成功,但用CDC::SelectObject 的时候失败。MSDN只有在CreateBitmapIndirect 有说明:

    While the CreateBitmapIndirect function can be used to create color bitmaps, for performance reasons applications should use CreateBitmapIndirect to create monochrome bitmaps and CreateCompatibleBitmap to create color bitmaps. Whenever a color bitmap from CreateBitmapIndirect is selected into a device context, the system must ensure that the bitmap matches the format of the device context it is being selected into. Because CreateCompatibleBitmap takes a device context, it returns a bitmap that has the same format as the specified device context. Thus, subsequent calls to SelectObject are faster with a color bitmap from CreateCompatibleBitmap than with a color bitmap returned from CreateBitmapIndirect.

    虽然CreateBitmapIndirect函数可用于创建彩色位图,出于性能方面的应用程序应该使用CreateBitmapIndirect创建单色位图,用CreateCompatibleBitmap创建彩色位图...............................

    要创建彩色位图应用 CreateCompatibleBitmap 函数

     

    关于CreateBitmapIndirect  BITMAP参数的bmBits 创建成功后返回0的问题

     

    CBitmap::CreateBitmapIndirect函数的功能是用一个BITMAP结构体重的高度、宽度和位模式(如果指定了一个的话)来初始化一个位图。调用该函数时,用户可以设置bmBits字段为NULL或者设为像素位数据的地址(用以初始化该位图)。

    如您的代码那样,在执行了CBitmap::GetBitmap之后所得的bm.bmBits确实为NULL,为了获得bmBits,您可以调用专门的CBitmap::GetBitmapBits函数来获得位数据。

    BYTE bitbuffer[16];
    DWORD ret3 = m_aBmp.GetBitmapBits(16, (LPVOID)bitbuffer);//检查bitbuffer中内容,的确是原来的位数据

     

    BITMAP bmWidthBytes  计算方法

    typedef    struct    tagBITMAP    {     
        
               LONG    bmType;                //必需为0   
               LONG    bmWidth;              //位图的宽度(以像素为单位)   
               LONG    bmHeight;            //位图的高度(以像素为单位)   
        
               /*指定每条光栅所占字节数。此值必须取偶数,   
                  因为图形设备接口(GDI)默认为一个位图的位值组成一个2字节的整数数组。*/   
               LONG    bmWidthBytes;     
        
               WORD    bmPlanes;            //    位图调色板颜色数   
        
               WORD    bmBitsPixel;      //    一个点在每个调色板上接近的颜色位数   
        
               LPVOID    bmBits;            //   指向存储像素阵列的数组   
        
       }    BITMAP;

    bmWidthBytes : 一行像素所占的字节数,一行像素的存储必须按word对齐,所以该值必须为2的倍数。

    单色图像 bmWidthBytes =bmWidth/8+(bmWidth/8)%2

    256(8位)色图像 bmWidthBytes=bmWidth+bmWidth%2;

    16色图像 bmWidthBytes=bmWidth/2+(bmWidth/2)%2;


    //windows程序设计(第五版)14.4.9 GrafMenu程序示例解决办法,部分代码

    /缩放位图分辨率
    HBITMAP StretchBitmap(HBITMAP hBitmap1)
    {
    	BITMAP bm1,bm2;
    	HBITMAP hBitmap2;
    	HDC hdc,hdcMem1,hdcMem2;
    	int cxChar,cyChar;
    	//获取系统字体宽高
    	cxChar=GetDialogBaseUnits()&0xffff;
    	cyChar=(GetDialogBaseUnits()>>16)&0xffff;
    	//创建两个兼容的内存显示设备
           hdc=CreateIC(TEXT("DISPLAY"),NULL,NULL,NULL);
    	 hdcMem1=CreateCompatibleDC(hdc);
    	 hdcMem2=CreateCompatibleDC(hdc);
    
    	 //获取位图信息
    	 GetObject(hBitmap1,sizeof(BITMAP),&bm1);
    	 //在系统字体大小的基础上缩放尺寸
    	 bm2=bm1;
    	 bm2.bmWidth=(cxChar*bm2.bmWidth)/4;
    	 bm2.bmHeight=(cyChar*bm2.bmHeight)/8;
    	 
    
    	 //创建位图2  CreateBitmapIndirect不能创建彩色位图,只能创建单色位图
    	 //hBitmap2=CreateBitmapIndirect(&bm2);
            //创建彩色位图	 
    	 hBitmap2=CreateCompatibleBitmap(hdc,bm2.bmWidth,bm2.bmHeight);
    
    	 //将位图选入内存,做StretchBlt放大或缩小位图
    	 SelectObject(hdcMem1,hBitmap1);
    	 SelectObject(hdcMem2,hBitmap2);
    
    	 StretchBlt(hdcMem2,0,0,bm2.bmWidth,bm2.bmHeight,hdcMem1,0,0,bm1.bmWidth,bm1.bmHeight,SRCCOPY);
    
    	 DeleteDC(hdc);
    	 DeleteDC(hdcMem1);
    	 DeleteDC(hdcMem2);
    	 DeleteObject(hBitmap1);
         return hBitmap2;
    }


  • 相关阅读:
    作业
    复习整理3
    复习整理2
    复习整理1
    书籍-os 相关
    书籍正则
    书籍
    SocketServer 简化编写网络服务器的步骤
    socket 粘包
    经典排序算法
  • 原文地址:https://www.cnblogs.com/xieyuan/p/3787440.html
Copyright © 2020-2023  润新知