zoukankan      html  css  js  c++  java
  • 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;
    }


  • 相关阅读:
    POJ 3710 Christmas Game#经典图SG博弈
    POJ 2599 A funny game#树形SG(DFS实现)
    POJ 2425 A Chess Game#树形SG
    LeetCode Array Easy 122. Best Time to Buy and Sell Stock II
    LeetCode Array Easy121. Best Time to Buy and Sell Stock
    LeetCode Array Easy 119. Pascal's Triangle II
    LeetCode Array Easy 118. Pascal's Triangle
    LeetCode Array Easy 88. Merge Sorted Array
    ASP.NET MVC 学习笔记之 MVC + EF中的EO DTO ViewModel
    ASP.NET MVC 学习笔记之面向切面编程与过滤器
  • 原文地址:https://www.cnblogs.com/xieyuan/p/3787440.html
Copyright © 2011-2022 走看看