一.问题
最近在使用CImage类生成图片时,遇到了一个问题,输出的图片上下颠倒,这是什么情况,如何将图片上下颠倒(或者左右颠倒呢),后来来查阅了资料,发现在使用StretchBlt时,通过参数设置可以实现。
二.解决方案
1.首先看一下StretchBlt这个函数功能:
该函数从源矩形中复制一个位图到目标矩形,必要时按目标设备设置的模式进行图像的拉伸或压缩。(函数简介资料来自百度百科)
BOOL StretchBlt(HDC hdcDest, int nXOriginDest, int nYOriginDest, int nWidthDest, int nHeightDest, HDC hdcSrc, int nXOriginSrc, int nYOriginSrc, int nWidthSrc, int nHeightSrc, DWORD dwRop);
hdcDest:指向目标设备环境的句柄。
nXOriginDest:指定目标矩形左上角的X轴坐标,按逻辑单位表示坐标。
nYOriginDest:指定目标矩形左上角的Y轴坐标,按逻辑单位表示坐标。
nWidthDest:指定目标矩形的宽度,按逻辑单位表示宽度。
nHeightDest:指定目标矩形的高度,按逻辑单位表示高度。
hdcSrc:指向源设备环境的句柄。
nXOriginSrc:指向源矩形区域左上角的X轴坐标,按逻辑单位表示坐标。
nYOriginSrc:指向源矩形区域左上角的Y轴坐标,按逻辑单位表示坐标。
nWidthSrc:指定源矩形的宽度,按逻辑单位表示宽度。
nHeightSrc:指定源矩形的高度,按逻辑单位表示高度。
dwRop:指定要进行的光栅操作。光栅操作码定义了系统如何在输出操作中组合颜色,这些操作包括刷子、源位图和目标位图等对象。参考BitBlt可了解常用的光栅操作码列表。
2.使用场景
使用opengl在当前设备上下文(源HDC)中绘制图形,作为源位图数据,然后利用StretchBlt函数,将源位图数据拷贝至CImage的目标设备上下文(目标HDC),在使用StretchBlt函数时,通过参数设置将源位图数据上下颠倒放入目标HDC,再由CImage导出颠倒后的图片,实现源图片的位置变换
部分代码如下:
//在此前使用Opengl绘制了图形数据,存放于内存BYTE* m_lpBitsOut
HDC curDC=CreateCompatibleDC(NULL); //该函数创建一个与指定设备兼容的内存设备上下文环境(DC)。通过GetDc()获取的HDC直接与相关设备沟通,而本函数创建的DC,则是与内存中的一个表面相关联。
BYTE *pBits=NULL;
//该函数提供一个指针,该指针指向位图位数据值的地方。可以给文件映射对象提供句柄,函数使用文件映射对象//来创建位图,或者让系统为位图分配内存
HBITMAP hBitmap=CreateDIBection(curDC,(BITAMAPINFOR)&lpInfor,DIB_RGB_COLORS,(void**)&pBits,NULL,0);
//该函数选择一对象到指定的设备上下文环境中,该新对象替换先前的相同类型的对象
HBITMAP hPrev=(HBITMAP)::SelectObject(curDC,hBitmap);
//该函数使用指定的DIB位图中发现的颜色数据来设置位图中的像素
SetDIBits(curDC,hBitmap,0,m_height,m_lpBitsOut,&lpInfor,DIB_RGB_COLORS);
CImage img;
img.Create(m_width,m_height,24);
HDC desDC=imag.GetDC();
//设置拉伸压缩模式
SetStretchBlMode(desDC,HALFTONE);
//图片上下颠倒处理
StretchBlt(desDC,0,0,m_width,m_height,curDC,0,m_height,m_width,-m_height,SRCCOPY);
free(m_lpBitsOut);
HRESULT hResult=imag.Save(fileDir);
//释放资源
|