Windows程序设计 读书笔记 与设备无关的位图DIB

一、DIB内的位图基本上没有经过任何压缩。

  DIB的扩展名是.BMP或者.DIB

  与大多数位图格式不同的是,DIB从底部开始,水平向上扫描图片。

  JPEG,GIF 是压缩后的DIB。

二、位图操作:

  1,打开位图

    hFile = CreateFile (pstrFileName, GENERIC_READ, FILE_SHARE_READ, NULL,
                         OPEN_EXISTING, FILE_FLAG_SEQUENTIAL_SCAN, NULL) ;

  2,读取位图

    dwFileSize = GetFileSize (hFile, &dwHighSize) ;

    pbmfh = malloc (dwFileSize) ;

    ReadFile (hFile, pbmfh, dwFileSize, &dwBytesRead, NULL) ;

  3,读取位图信息

       static BITMAPINFO       * pbmi ;
       static BYTE             * pBits ;

    pbmi  = (BITMAPINFO *) (pbmfh + 1) ;
        pBits = (BYTE *) pbmfh + pbmfh->bfOffBits ;

    if (pbmi->bmiHeader.biSize == sizeof (BITMAPCOREHEADER))
               {
                    cxDib = ((BITMAPCOREHEADER *) pbmi)->bcWidth ;
                    cyDib = ((BITMAPCOREHEADER *) pbmi)->bcHeight ;
               }
               else
               {
                    cxDib =      pbmi->bmiHeader.biWidth ;
                    cyDib = abs (pbmi->bmiHeader.biHeight) ;
               }

  4,显示位图:

    SetDIBitsToDevice (hdc,
                                  100,         // xDst
                                  100,         // yDst
                                  cxDib,     // cxSrc
                                  cyDib,     // cySrc
                                  0,         // xSrc
                                  0,         // ySrc
                                  0,         // first scan line
                                  cyDib,     // number of scan lines
                                  pBits,
                                  pbmi,
                                  DIB_RGB_COLORS) ;

    SetDIBitsToDevice没有掩码参数

    如果位图过大,可以采取连续显示方法,就是每次读一行或几行,然后SetDIBitsToDevice显示出来,例子见seqdisp。

    StretchDIBits (hdc, 0, 0, cxClient, cyClient,
                                     0, 0, cxDib, cyDib,
                                pBits, pbmi, DIB_RGB_COLORS, SRCCOPY) ;

    StretchDIBits和SetDIBitsToDevice的关系等同与Bitblt和StretchBlt的关系。但StretchDIBits有掩码参数。

    另外StretchDIBits不能通过连续显示节省内存。

  5,保存位图

    hFile = CreateFile (pstrFileName, GENERIC_WRITE, 0, NULL,
                         CREATE_ALWAYS, FILE_ATTRIBUTE_NORMAL, NULL) ;

    WriteFile (hFile, pbmfh, pbmfh->bfSize, &dwBytesWritten, NULL) ;

 三、DIB和DDB转化

  1,从DIB 到 DDB

   1.1 如上面,用ReadFile打开DIB后,hBitmap = CreateDIBitmap (hdc, (BITMAPINFOHEADER *) (pbmfh + 1),CBM_INIT,
    (BYTE *) pbmfh + pbmfh->bfOffBits,(BITMAPINFO *) (pbmfh + 1),DIB_RGB_COLORS) ;

    如果CreateDIBitmap的时候没有初始化像素位,可以用SetDIBits

   1.2 CreateDIBSection 创建位图的一部分:位图像素位的内存块 bits

    创建的内存块归系统所有,传输速度快,能用指针直接改变DIB位。deleteobject(hbitmap)的时候系统自动释放内存块。

    步骤:同上,读取pbmi后,

    CreateDIBSection (NULL, pbmi, DIB_RGB_COLORS, &pBits, NULL, 0) ;

    ReadFile (hFile, pBits, bmfh.bfSize - bmfh.bfOffBits, &dwBytesRead, NULL) ;

  2 从DDB到DIB

    GetDIBits

    但此方法一般不用,因为如果有HBITMAP句柄的话,一定会有创建这个句柄的资源。而DDB包含的信息会比较少,所以不如直接从资源中保存。

原文地址:https://www.cnblogs.com/aoyihuashao/p/1722952.html