顾乔芝士网

持续更新的前后端开发技术栈

Windows API操作BMP图像(3)BMP图像的显示

在Windows窗口上显示BMP图像代码如下所示。这里主要用到了StretchDIBits()函数,此函数将BMP图像像素拷贝到显示设备上下文中,拉伸并显示出来。如果是索引图像,则需要先创建逻辑调色板,并调用SelectPalette()函数选用这个逻辑调色板;如果是真彩色图像,则没有调色板。 Windows系统中调色板使用CPalette类,调色板大小一般由信息头的biClrUsed成员指定,如果 biClrUsed值为0,则没有调色板。

在Windows窗口中显示BMP图像

//功能:在Windows窗口中显示BMP图像
//输入:hDC,显示设备上下文句柄;
//rectDC, 图像显示在设备中的位置;
//输入:bmpHeader,BITMAPINFO结构体指针,包含位图信息头和调色板;
//输入:pBmp,图像像素数据;
//返回值:显示成功返回TRUE
#define PALVERSION 0x300
BOOL DisplayBMPImg(const HDC &hDC, const CRect &rectDst, 
const BITMAPINFO *bmpHeader, const unsigned char *pBmpBits)
{
  BITMAPINFOHEADER infoHeader = bmpHeader->bmiHeader;
  //创建Windows调色板
  CPalette palette;
  HPALETTE pOldPalette = NULL;
  LOGPALETTE *pLP = NULL;
  if (infoHeader.biBitCount > 0 && infoHeader.biBitCount < 16) {
    int nNumClrs = infoHeader.biClrUsed; //从信息头得到调色板大小
    if (0 == nNumClrs) { //如果没有调色板大小为0
      //直接计算得到图像所用颜色数
      nNumClrs = pow(float(2), infoHeader.biBitCount);
    }
    //计算逻辑调色板所需空间
    DWORD nSize = sizeof(LOGPALETTE) + sizeof(PALETTEENTRY)*nNumClrs;
    pLP = (LOGPALETTE*) new unsigned char[nSize];
    //初始化逻辑调色板
    pLP->palVersion = PALVERSION; //固定值
    pLP->palNumEntries = nNumClrs;
    for (int i = 0; i < nNumClrs; i++) {
      pLP->palPalEntry[i].peRed =  bmpHeader->bmiColors[i].rgbRed;
      pLP->palPalEntry[i].peGreen = bmpHeader->bmiColors[i].rgbGreen;
      pLP->palPalEntry[i].peBlue = bmpHeader->bmiColors[i].rgbBlue;
      pLP->palPalEntry[i].peFlags = 0;
    }
    //创建调色板
    palette.CreatePalette(pLP);
    HPALETTE hPal = (HPALETTE)palette.m_hObject;
    //系统选用新的调色板,并保存旧的调色板
    pOldPalette = ::SelectPalette(hDC, hPal, FALSE);
  }
  //设置图像显示的拉伸模式,解决位图显示的失真问题
  ::SetStretchBltMode(hDC, COLORONCOLOR);
  //调用WindowsAPI函数显示位图图像
  BOOL bSuccess = ::StretchDIBits(hDC, //设备上下文句柄
       rectDst.left, //目标矩形x坐标
       rectDst.top, //目标矩形y坐标
       rectDst.Width(), //目标矩形宽度
       rectDst.Height(), //目标矩形高度
       0, //图像起点x坐标
       0, //图像起点y坐标
       infoHeader.biWidth, // 图像宽度
       abs(infoHeader.biHeight), //图像高度
       pBmpBits, // 图像像素指针
       bmpHeader, //BITMAPINFO结构体指针
       DIB_RGB_COLORS, // wUsage
       SRCCOPY); // dwROP
  //恢复原有调色板
  if (NULL != pOldPalette) {
    pOldPalette = ::SelectPalette(hDC, pOldPalette, FALSE);
  }
  palette.DeleteObject(); //删除调色板对象
  if (NULL != pLP) {
    delete[] pLP;
  }
  return TRUE;
}
控制面板
您好,欢迎到访网站!
  查看权限
网站分类
最新留言