头文件如下:
- /********************************************************************
- Copyright(c) 2011,
- All rights reserved.
- purpose: 图片加载使用类
- 当前版本: 1.0
- 作 者: zhangwf
- 创建日期: 2011:9:6
- 完成日期:
- 取代版本:
- 作 者:
- 完成日期:
- *********************************************************************/
- #ifndef _WF_BITMAP_H_
- #define _WF_BITMAP_H_
- //
- #include <Windows.h>
- #include <imaging.h>
- #include "WFRect.h"
- //
- class CWFBitmap
- {
- public:
- // 构造函数
- CWFBitmap();
- // 析构函数
- ~CWFBitmap();
- // 拷贝构造函数
- CWFBitmap(const CWFBitmap &other);
- // 赋值函数
- CWFBitmap& operator=(const CWFBitmap &other);
- //
- public: // 图像加载释放、图像大小相关接口
- // 从文件中加载
- BOOL LoadFromFile(
- LPCWSTR lpFileName // 文件绝对路径
- );
- // 从资源中加载,例如LoadFromResource(MAKEINTRESOURCE(IDR_BACKIMG), _T("PNG"));
- BOOL LoadFromResource(
- LPCWSTR lpName, // 资源名称比如:MAKEINTRESOURCE(IDR_BACKIMG)
- LPCWSTR lpType // 资源类型比如:_T("PNG")
- );
- // 从缓冲区中加载(该缓冲区为整个图像文件数据缓冲区,包括文件头等一切文件信息)
- BOOL LoadFromBuffer(
- const unsigned char *pBuf, // 缓冲区地址
- DWORD dwcbBufSize // 缓冲区字节大小
- );
- // 从IImage对象中加载
- BOOL LoadFromIImage(
- IImage *pIImage // IImage对象
- );
- // 从IBitmapImage对象中加载(内部会生成新的IBitmapImage用于拷贝原数据)
- BOOL LoadFromIBitmapImage(
- IBitmapImage *pBitmapImage // IBitmapImage对象
- );
- // 释放占用的资源
- void Release(void);
- // 获得图像的宽度,未加载到图片返回0
- DWORD Width() const;
- // 获得图像的高度,未加载到图片返回0
- DWORD Height() const;
- //
- public: // 图像绘制相关接口
- // 绘制整个图像到指定位置(会把图像压缩或拉伸填充到指定区域)
- void Draw(
- HDC hdc, // 绘制DC
- const RECT* dstRect // 绘制目标区域
- );
- // 绘制图像上一部分到指定的部分(先绘制到内存DC,再绘制到目标DC)
- void Draw(
- HDC hdc, // 绘制DC
- const RECT* dstRect, // 绘制目标区域
- const RECT* srcRect // 待绘制图片上的指定区域,NULL表示整个图片
- );
- // 绘制图像上一部分到指定的区域(支持alpha混合)
- void DrawAlpha(
- HDC hdc, // 绘制DC
- const RECT* dstRect, // 绘制目标区域
- const RECT* srcRect // 待绘制图片上的指定区域,NULL表示整个图片
- );
- // 绘制整个图像到自定义矩形类型区域(会把图像压缩或拉伸填充到指定区域)
- void DrawEx(
- HDC hdc, // 绘制DC
- const CWFRect* dstRect // 绘制目标区域
- );
- // 绘制图像上一部分到指定的自定义矩形类型区域(先绘制到内存DC,再绘制到目标DC)
- void DrawEx(
- HDC hdc, // 绘制DC
- const CWFRect* dstRect, // 绘制目标区域
- const CWFRect* srcRect // 待绘制图片上的指定区域,NULL表示整个图片
- );
- // 绘制图像上一部分到指定的自定义矩形类型区域(支持alpha混合)
- void DrawAlphaEx(
- HDC hdc, // 绘制DC
- const CWFRect* dstRect, // 绘制目标区域
- const CWFRect* srcRect // 待绘制图片上的指定区域,NULL表示整个图片
- );
- //
- public: // 图像缩放旋转等相关接口
- // 缩放图像到IImage对象中,不改变自身数据
- typedef IImage* PWFIImage;
- BOOL ZoomToIImage(
- PWFIImage &pDstIImage, // 存放缩放后图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放
- DWORD dwNewWidth, // 缩放后图像宽度
- DWORD dwNewHeight // 缩放后图像高度
- );
- // 缩放图像(指定缩放后图像的宽度和高度)
- BOOL Zoom(
- DWORD dwNewWidth, // 缩放后图像宽度
- DWORD dwNewHeight // 缩放后图像高度
- );
- // 缩放图像到目标对象中(指定缩放后图像的宽度和高度),不改变对象自身
- BOOL Zoom(
- CWFBitmap &dstBitmap, // 带出缩放后的图像
- DWORD dwNewWidth, // 缩放后图像宽度
- DWORD dwNewHeight // 缩放后图像高度
- );
- // 缩放图像(指定缩放X方向,Y方向缩放比率)
- BOOL ZoomEx(
- double dbZoomXRatio, // X方向缩放率
- double dbZoomYRatio // Y方向缩放率
- );
- // 缩放图像到目标对象中(指定缩放X方向,Y方向缩放比率),不改变对象自身
- BOOL ZoomEx(
- CWFBitmap &dstBitmap, // 带出缩放后的图像
- double dbZoomXRatio, // X方向缩放率
- double dbZoomYRatio // Y方向缩放率
- );
- // 按特定角度旋转图像到IImage对象中,不改变自身数据
- // 顺时针旋转,只支持90, 180, 270, or 360
- BOOL RotateSpecificAngleToIImage(
- PWFIImage &pDstIImage, // 存放旋转后图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放
- float fSpecificAngle // 特定旋转角度(单位:度)
- );
- // 按特定角度旋转图像
- // 顺时针旋转,只支持90, 180, 270, or 360
- BOOL RotateSpecificAngle(
- float fSpecificAngle // 特定旋转角度(单位:度)
- );
- // 按特定角度旋转图像到目标对象中,不改变对象自身
- // 顺时针旋转,只支持90, 180, 270, or 360
- BOOL RotateSpecificAngle(
- CWFBitmap &dstBitmap, // 带出旋转后的图像
- float fSpecificAngle // 特定旋转角度(单位:度)
- );
- // 翻转图像到IImage对象中,不改变自身数据
- BOOL FlipToIImage(
- PWFIImage &pDstIImage, // 存放翻转后图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放
- BOOL bFilpX, // 是否反转X方向
- BOOL bFlipY // 是否反转Y方向
- );
- // 翻转图像
- BOOL Flip(
- BOOL bFilpX, // 是否反转X方向
- BOOL bFlipY // 是否反转Y方向
- );
- // 翻转图像到目标对象中,不改变对象自身
- BOOL Flip(
- CWFBitmap &dstBitmap, // 带出翻转后的图像
- BOOL bFilpX, // 是否反转X方向
- BOOL bFlipY // 是否反转Y方向
- );
- // 裁剪图像上指定区域到IImage对象中,不改变自身数据
- BOOL CutToIImage(
- PWFIImage &pDstIImage, // 存放裁剪图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放
- const RECT *pCutRect // 在图像上裁剪的区域
- );
- // 裁剪图像(图像改变为指定裁剪区域的图像)
- BOOL Cut(
- const RECT *pCutRect // 在图像上裁剪的区域
- );
- // 裁剪图像到目标对象中,不改变对象自身
- BOOL Cut(
- CWFBitmap &dstBitmap, // 带出裁剪到的图像
- const RECT *pCutRect // 在图像上裁剪的区域
- );
- // 生成缩略图到指定IImage对象中,不改变自身数据
- BOOL ThumbnailToIImage(
- PWFIImage &pDstIImage, // 存放缩略图的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放
- DWORD dwThumbWidth, // 缩略图宽度
- DWORD dwThumbHeight // 缩略图高度
- );
- // 生成缩略图(指定像素宽度高度)(图像改变为缩略图)
- BOOL Thumbnail(
- DWORD dwThumbWidth, // 缩略图宽度
- DWORD dwThumbHeight // 缩略图高度
- );
- // 生成缩略图(指定缩放比率)(图像改变为缩略图)
- BOOL ThumbnailEx(
- double dbXRatio, // X方向缩放率
- double dbYRatio // Y方向缩放率
- );
- // 生成缩略图到目标对象中(指定像素宽度高度),不改变对象自身
- BOOL Thumbnail(
- CWFBitmap &dstBitmap, // 带出旋转后的图像
- DWORD dwThumbWidth, // 缩略图宽度
- DWORD dwThumbHeight // 缩略图高度
- );
- // 生成缩略图到目标对象中(指定缩放比率),不改变对象自身
- BOOL ThumbnailEx(
- CWFBitmap &dstBitmap, // 带出旋转后的图像
- double dbXRatio, // X方向缩放率
- double dbYRatio // Y方向缩放率
- );
- // 图像旋转任意角度到IBitmapImage对象中,不改变自身数据
- // 若只需要旋转90,180,270,360请调用接口RotateSpecificAngleToIImage
- typedef IBitmapImage* PWFIBitmapImage;
- BOOL RotateToIBitmapImage(
- PWFIBitmapImage &pDstIBitmapImage, // 存放旋转后图像的IBitmapImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放
- float fAngle // 特定旋转角度(单位:度)
- );
- // 按任意角度旋转图像
- // 若只需要旋转90,180,270,360请调用接口RotateSpecificAngle
- BOOL Rotate(
- float fAngle // 特定旋转角度(单位:度)
- );
- // 按任意角度旋转图像到目标对象中,不改变对象自身
- // 若只需要旋转90,180,270,360请调用接口RotateSpecificAngle
- BOOL Rotate(
- CWFBitmap &dstBitmap, // 带出旋转后的图像
- float fAngle // 特定旋转角度(单位:度)
- );
- //
- public: // 取得图像颜色数据相关接口
- // 获得图像数据(只含有各个点的颜色信息)
- BOOL GetColorBuf(
- unsigned char *pDataBuf, // 存放图像数据缓冲区
- DWORD dwcbBufSize, // 缓冲区实际大小(需要的大小通常是(宽度*高度*4))
- DWORD *pdwRealGetBytes=NULL // 实际取得数据字节大小
- );
- // 获得图片数据(只含有各个点的颜色信息)缓冲区地址,返回NULL表示没有图片数据
- const unsigned char* GetColorBufAddr(
- DWORD *pdwcbBufSize // 带出颜色缓冲区字节大小
- );
- //
- private: // 私有成员变量
- IImage *m_pImage; // 保存图像数据
- ImageInfo m_ImageInfo; // 图像信息
- unsigned char *m_pImgDataBuf; // 保存原始图像数据(带有alpha通道数据)
- DWORD m_dwcbImgDataBufSize; // 图像数据字节大小
- IBitmapImage *m_pBitmapImage; // 位图指针
- // 先绘制到内存DC上,再次绘制直接由内存DC拷贝到目标DC
- HDC m_hDrawDC; // 临时保存DC
- HBITMAP m_hBitmap; // 临时保存图片
- HBITMAP m_hOldBitmap;
- // 静态成员变量
- static DWORD m_dwObjCounts; // 对象数量
- static IImagingFactory *m_pImagingFactory; // Image工厂接口对象
- private: // 私有函数
- // 创建与释放Image工厂接口对象
- static BOOL CreateImagingFactory(void);
- static void DeleteImagingFactory(void);
- // 为图片创建内存DC,及清除内存DC
- HDC CreateImgDC(HDC hdc);
- void DeleteImgDC(void);
- // 取得图片原始数据,及销毁图片原始数据
- BOOL CreateImgDateBuf(void);
- void DeleteImgDateBuf(void);
- // 拷贝一个IBitmapImage到另一个IBitmapImage中
- static BOOL CopyBitmapImage(
- IBitmapImage *pSrcBitmapImage, // 源IBitmapImage
- PWFIBitmapImage &pDstBitmapImage // 目标IBitmapImage
- );
- };
- //
- #endif
源文件如下:
- /********************************************************************
- Copyright(c) 2011,
- All rights reserved.
- purpose: 图片加载使用类
- 当前版本: 1.0
- 作 者: zhangwf
- 创建日期: 2011:9:6
- 完成日期:
- 取代版本:
- 作 者:
- 完成日期:
- *********************************************************************/
- #include "WFBitmap.h"
- #include <initguid.h>
- #include <imgguids.h>
- //
- // 声明及实现不需要给出接口的全局函数
- // 路径是否有效
- BOOL WFBING_PathEffective(LPCWSTR lpPathName);
- // 旋转图像数据缓冲区
- typedef BYTE* PWFBYTE;
- BOOL WFBING_RotateImageBuffer(
- const BYTE* pSrcBuf, // 待旋转原图像缓冲区(32位色,每个点有ARGB四个通道),缓冲区大小不能小于高度*宽度*4
- DWORD dwSrcWidth, // 原图像像素宽度
- DWORD dwSrcHeight, // 原图像像素高度
- double dbRotateAngle, // 顺时针旋转角度(单位:度)
- PWFBYTE &pDstBuf, // 输出旋转后图像缓冲区(32位色,每个点有ARGB四个通道),带出的缓冲区大小为高度*宽度*4,需要外部释放
- DWORD &dwDstWidth, // 输出旋转后图像像素宽度
- DWORD &dwDstHeight, // 输出旋转后图像像素高度
- DWORD dwFillColor = 0x00FFFFFF // 填充色(旋转后的图像比原图像大,空的部分使用该白色全透明颜色填充,ALPHA通道为0表示全透明)
- );
- //
- // 路径是否有效
- BOOL WFBING_PathEffective(LPCWSTR lpPathName)
- {
- // 参数有效性
- if (lpPathName == NULL)
- {
- return FALSE;
- }
- // 是否可以取得属性
- return (::GetFileAttributesW(lpPathName) == INVALID_FILE_ATTRIBUTES) ? FALSE : TRUE;
- }
- // 旋转图像数据缓冲区
- typedef BYTE* PWFBYTE;
- BOOL WFBING_RotateImageBuffer(
- const BYTE* pSrcBuf, // 待旋转原图像缓冲区(32位色,每个点有ARGB四个通道)
- DWORD dwSrcWidth, // 原图像像素宽度
- DWORD dwSrcHeight, // 原图像像素高度
- double dbRotateAngle, // 顺时针旋转角度(单位:度)
- PWFBYTE &pDstBuf, // 输出旋转后图像缓冲区(32位色,每个点有ARGB四个通道),带出的缓冲区大小为高度*宽度*4,需要外部释放
- DWORD &dwDstWidth, // 输出旋转后图像像素宽度
- DWORD &dwDstHeight, // 输出旋转后图像像素高度
- DWORD dwFillColor // 填充色(旋转后的图像比原图像大,空的部分使用该白色全透明颜色填充,ALPHA通道为0表示全透明)
- )
- {
- // 参数有效性
- if (pSrcBuf==NULL || dwSrcWidth==0 || dwSrcHeight==0)
- {
- return FALSE;
- }
- // 计算有效的旋转角,旋转一周视为没有旋转
- double dbAngle = (dbRotateAngle - (int)dbRotateAngle) + ((int)dbRotateAngle%360);
- // 旋转角度过小不需要旋转,直接拷贝缓冲区
- if (dbAngle>=-0.0000001 && dbAngle<=0.0000001)
- {
- DWORD dwDstBufSize = dwSrcWidth*dwSrcHeight*4;
- pDstBuf = new BYTE[dwDstBufSize];
- if (pDstBuf == NULL)
- {
- printf("Rotate Angle Zero New Buf Error!\n");
- return FALSE;
- }
- // 拷贝数据
- memset(pDstBuf, 0, dwDstBufSize);
- memcpy(pDstBuf, pSrcBuf, dwDstBufSize);
- dwDstWidth = dwSrcWidth;
- dwDstHeight = dwSrcHeight;
- return TRUE;
- }
- // 计算sin(dbAngle)和cos(dbAngle)的值
- double dbPI = 3.1415926535;
- double dbA = dbAngle*dbPI/180;
- double dbSinA = sin(dbA);
- double dbCosA = cos(dbA);
- // 计算除去左上顶点外的其他三个顶点旋转后坐标
- // 旋转坐标公式:X'= X*cosθ - Y*sinθ;Y' = X*sinθ + Y*cosθ;其中θ为顺时针旋转角度
- // 以图像左上角为原点,向右为X正方向,向下为Y正方向;
- // 其他顶点坐标为(dwSrcWidth, 0),(dwSrcWidth, dwSrcHeight),(0, dwSrcHeight)
- double dbX1 = (double)dwSrcWidth*dbCosA - 0*dbSinA;
- double dbY1 = (double)dwSrcWidth*dbSinA + 0*dbCosA;
- double dbX2 = (double)dwSrcWidth*dbCosA - (double)dwSrcHeight*dbSinA;
- double dbY2 = (double)dwSrcWidth*dbSinA + (double)dwSrcHeight*dbCosA;
- double dbX3 = 0*dbCosA - (double)dwSrcHeight*dbSinA;
- double dbY3 = 0*dbSinA + (double)dwSrcHeight*dbCosA;
- // 计算旋转后4个顶点XY方向最大最小坐标值,用于确定旋转后图像大小
- double dbMaxX = max(dbX3, max(dbX2, max(0, dbX1)));
- double dbMinX = min(dbX3, min(dbX2, min(0, dbX1)));
- double dbMaxY = max(dbY3, max(dbY2, max(0, dbY1)));
- double dbMinY = min(dbY3, min(dbY2, min(0, dbY1)));
- // 计算旋转后图像的宽度和高度
- DWORD dwUseWidth = (DWORD)fabs(dbMaxX - dbMinX) + 1;
- DWORD dwUseHeight = (DWORD)fabs(dbMaxY - dbMinY) + 1;
- // 为旋转后图像申请数据缓冲区
- pDstBuf = new BYTE[dwUseWidth*dwUseHeight*4];
- if (pDstBuf == NULL)
- {
- printf("Rotate Angle New Buf[%d] Error!\n", dwUseWidth*dwUseHeight*4);
- return FALSE;
- }
- // 带出旋转后图像大小
- dwDstWidth = dwUseWidth;
- dwDstHeight = dwUseHeight;
- // 旋转后的图像会出现超出坐标系区域,需要坐标平移
- // 旋转平移变换坐标公式:X'= X*cosθ - Y*sinθ - dbMinX;Y' = X*sinθ + Y*cosθ - dbMinY;其中θ为顺时针旋转角度
- // 填充旋转后图像数据时就需要直到每个点对应原图像位置,所以公式变换为:
- // X = (X'+dbMinX)*cosθ + (Y'+dbMinY)*sinθ;
- // Y = (Y'+dbMinY)*conθ - (X'+dbMinX)*sinθ;
- // 计算出的原图像上(X,Y)坐标不是整数,到底选取哪一点的颜色值来填充旋转后的区域呢?
- // 若(X,Y)不在原图像区域上,则用默认颜色填充;
- // 若在元图像上,从图像质量及效率的考虑上,通常选择双线性插值获取旋转后该位置的颜色
- // 双线性插值取的是与(X,Y)临近的4个点的颜色值来计算旋转后该位置的颜色值
- /************************************************************************************
- 双线性内插值:
- 对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为(i+u,j+v),
- 其中i、j均为非负整数,u、v为[0,1)区间的浮点数,则这个像素得值f(i+u,j+v)可由原图像
- 中坐标为 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定,
- 即:f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)
- 其中f(i,j)表示源图像(i,j)处的的像素值,以此类推。
- ************************************************************************************/
- // 遍历目标图像上每一个点,依次填充颜色
- double dbSrcX = 0; // 对应原图像上X坐标位置(不为整数)
- double dbSrcY = 0; // 对应原图像上Y坐标位置(不为整数)
- DWORD dwSrcI = 0; // 对应dbSrcX的整数部分
- DWORD dwSrcJ = 0; // 对应dbSrcY的整数部分
- double dbSrcU = 0; // 对应dbSrcX-dwSrcI
- double dbSrcV = 0; // 对应dbSrcY-dwSrcJ
- DWORD *pdwDstBuf = (DWORD*)pDstBuf; // 以4字节方式使用目标缓冲区
- DWORD *pdwSrcBuf = (DWORD*)pSrcBuf; // 以4字节方式使用原图像缓冲区
- BYTE *pByteTmpBuf = NULL; // 临时使用指针
- DWORD *pSrcIJ = NULL; // (I,J)位置颜色
- DWORD *pSrcI1J = NULL; // (I+1,J)位置颜色
- DWORD *pSrcIJ1 = NULL; // (I,J+1)位置颜色
- DWORD *pSrcI1J1 = NULL; // (I+1,J+1)位置颜色
- DWORD dwY = 0;
- DWORD dwX = 0;
- DWORD dwColorBit = 0;
- for (dwY=0; dwY<dwUseHeight; dwY++)
- {
- for (dwX=0; dwX<dwUseWidth; dwX++)
- {
- // 坐标变换公式
- // X = (X'+dbMinX)*cosθ + (Y'+dbMinY)*sinθ;
- // Y = (Y'+dbMinY)*conθ - (X'+dbMinX)*sinθ;
- dbSrcX = ((double)dwX + dbMinX)*dbCosA + ((double)dwY + dbMinY)*dbSinA;
- dbSrcY = ((double)dwY + dbMinY)*dbCosA - ((double)dwX + dbMinX)*dbSinA;
- // 坐标点不在原图像区域,使用默认颜色填充
- if (dbSrcX<0 || dbSrcX>=(double)dwSrcWidth || dbSrcY<0 || dbSrcY>=(double)dwSrcHeight)
- {
- pdwDstBuf[dwY*dwUseWidth + dwX] = dwFillColor;
- }
- // 在原图像范围内,则使用双线性插值计算当前颜色
- else
- {
- // 计算位置
- dwSrcI = (DWORD)dbSrcX;
- dwSrcJ = (DWORD)dbSrcY;
- dbSrcU = dbSrcX - dwSrcI;
- dbSrcV = dbSrcY - dwSrcJ;
- // 得到临近4个位置颜色位置指针
- pSrcIJ = pdwSrcBuf + (dwSrcJ*dwSrcWidth + dwSrcI);
- pSrcI1J = (dwSrcI+1 < dwSrcWidth) ? (pSrcIJ + 1) : pSrcIJ;
- pSrcI1J1 = (dwSrcI+1<dwSrcWidth && dwSrcJ+1<dwSrcHeight) ? (pdwSrcBuf + ((dwSrcJ+1)*dwSrcWidth + dwSrcI + 1)) : pSrcIJ;
- pSrcIJ1 = (dwSrcJ+1 < dwSrcHeight) ? (pdwSrcBuf + ((dwSrcJ+1)*dwSrcWidth + dwSrcI)) : pSrcIJ;
- // 根据插值公式计算颜色值
- // f(i+u,j+v) = (1-u)(1-v)f(i,j) + (1-u)vf(i,j+1) + u(1-v)f(i+1,j) + uvf(i+1,j+1)
- pByteTmpBuf = (BYTE*)(pdwDstBuf + (dwY*dwUseWidth + dwX));
- for (dwColorBit=0; dwColorBit<4; dwColorBit++)
- {
- pByteTmpBuf[dwColorBit] = (BYTE)( (1-dbSrcU)*(1-dbSrcV)*((BYTE*)pSrcIJ)[dwColorBit]
- + (1-dbSrcU)*dbSrcV*((BYTE*)pSrcIJ1)[dwColorBit]
- + dbSrcU*(1-dbSrcV)*((BYTE*)pSrcI1J)[dwColorBit]
- + dbSrcU*dbSrcV*((BYTE*)pSrcI1J1)[dwColorBit]
- );
- }
- }
- }
- }
- // 旋转成功
- return TRUE;
- }
- //
- // 初始化静态成员变量
- DWORD CWFBitmap::m_dwObjCounts = 0;
- IImagingFactory* CWFBitmap::m_pImagingFactory = NULL;
- //
- // 构造函数
- CWFBitmap::CWFBitmap()
- : m_pImgDataBuf(NULL)
- , m_dwcbImgDataBufSize(0)
- {
- // 创建Image工厂接口对象
- CreateImagingFactory();
- // 初始化变量
- m_pImage = NULL;
- memset(&m_ImageInfo, 0, sizeof(m_ImageInfo));
- m_hDrawDC = NULL;
- m_hBitmap = NULL;
- m_hOldBitmap = NULL;
- m_pBitmapImage = NULL;
- }
- // 析构函数
- CWFBitmap::~CWFBitmap()
- {
- // 释放占用资源
- Release();
- // 释放Image工厂接口对象
- DeleteImagingFactory();
- }
- // 拷贝构造函数
- CWFBitmap::CWFBitmap(const CWFBitmap &other)
- : m_pImgDataBuf(NULL)
- , m_dwcbImgDataBufSize(0)
- {
- // 创建Image工厂接口对象
- CreateImagingFactory();
- // 初始化变量
- m_pImage = NULL;
- memset(&m_ImageInfo, 0, sizeof(m_ImageInfo));
- m_hDrawDC = NULL;
- m_hBitmap = NULL;
- m_hOldBitmap = NULL;
- m_pBitmapImage = NULL;
- // 拷贝图片信息
- m_ImageInfo = other.m_ImageInfo;
- // 拷贝IImage
- if (other.m_pImage != NULL)
- {
- other.m_pImage->QueryInterface(IID_IImage, (void **)&m_pImage);
- }
- // 拷贝图片数据
- if (other.m_pImgDataBuf!=NULL && other.m_dwcbImgDataBufSize!=0)
- {
- m_pImgDataBuf = new unsigned char[other.m_dwcbImgDataBufSize];
- if (m_pImgDataBuf != NULL)
- {
- m_dwcbImgDataBufSize = other.m_dwcbImgDataBufSize;
- memcpy(m_pImgDataBuf, other.m_pImgDataBuf, m_dwcbImgDataBufSize);
- }
- }
- }
- // 赋值函数
- CWFBitmap& CWFBitmap::operator=(const CWFBitmap &other)
- {
- // 检查自赋值
- if (this == &other)
- {
- return *this;
- }
- // 释放资源
- Release();
- // 拷贝图片信息
- m_ImageInfo = other.m_ImageInfo;
- // 拷贝IImage
- if (other.m_pImage != NULL)
- {
- other.m_pImage->QueryInterface(IID_IImage, (void **)&m_pImage);
- }
- // 拷贝图片数据
- if (other.m_pImgDataBuf!=NULL && other.m_dwcbImgDataBufSize!=0)
- {
- m_pImgDataBuf = new unsigned char[other.m_dwcbImgDataBufSize];
- if (m_pImgDataBuf != NULL)
- {
- m_dwcbImgDataBufSize = other.m_dwcbImgDataBufSize;
- memcpy(m_pImgDataBuf, other.m_pImgDataBuf, m_dwcbImgDataBufSize);
- }
- }
- // 返回当前对象
- return *this;
- }
- // 从文件中加载
- BOOL CWFBitmap::LoadFromFile(
- LPCWSTR lpFileName // 文件绝对路径
- )
- {
- // 释放上次图片数据
- Release();
- // 路径有效性
- if (WFBING_PathEffective(lpFileName) == FALSE)
- {
- return FALSE;
- }
- // 创建Image工厂接口对象失败
- if (m_pImagingFactory == NULL)
- {
- return FALSE;
- }
- // 从文件中创建图片
- HRESULT hr = NULL;
- if(FAILED(hr = m_pImagingFactory->CreateImageFromFile(lpFileName, &m_pImage)))
- {
- return FALSE;
- }
- // 得到图片信息
- if(FAILED(hr = m_pImage->GetImageInfo(&m_ImageInfo)))
- {
- return FALSE;
- }
- // 成功获得图片信息
- return TRUE;
- }
- // 从资源中加载,例如LoadFromResource(MAKEINTRESOURCE(IDR_BACKIMG), _T("PNG"));
- BOOL CWFBitmap::LoadFromResource(
- LPCWSTR lpName, // 资源名称比如:MAKEINTRESOURCE(IDR_BACKIMG)
- LPCWSTR lpType // 资源类型比如:_T("PNG")
- )
- {
- // 释放上次图片数据
- Release();
- // 创建Image工厂接口对象失败
- if (m_pImagingFactory == NULL)
- {
- return FALSE;
- }
- // 在资源中寻找
- HMODULE hModule_Current = ::GetModuleHandle(NULL);
- HRSRC hr = ::FindResource(hModule_Current, lpName, lpType);
- DWORD dwsize = ::SizeofResource(GetModuleHandle(NULL), hr);
- HGLOBAL hg = ::LoadResource(GetModuleHandle(NULL), hr);
- LPSTR lp = (LPSTR)::LockResource(hg);
- // 从缓冲区创建图片
- HRESULT hrt = NULL;
- if(FAILED(hrt = m_pImagingFactory->CreateImageFromBuffer(lp, dwsize, DISPOSAL_NONE, &m_pImage)))
- {
- ::DeleteObject(hr);
- return FALSE;
- }
- // 得到图片信息
- if(FAILED(hrt = m_pImage->GetImageInfo(&m_ImageInfo)))
- {
- ::DeleteObject(hr);
- return FALSE;
- }
- // 成功获得图片信息
- ::DeleteObject(hr);
- return TRUE;
- }
- // 从缓冲区中加载
- BOOL CWFBitmap::LoadFromBuffer(
- const unsigned char *pBuf, // 缓冲区地址
- DWORD dwcbBufSize // 缓冲区字节大小
- )
- {
- // 释放上次图片数据
- Release();
- // 参数有效性
- if (pBuf==NULL || dwcbBufSize==0)
- {
- return FALSE;
- }
- // 创建Image工厂接口对象失败
- if (m_pImagingFactory == NULL)
- {
- return FALSE;
- }
- // 从文件中创建图片
- HRESULT hr = NULL;
- if(FAILED(hr = m_pImagingFactory->CreateImageFromBuffer(pBuf, dwcbBufSize, DISPOSAL_NONE, &m_pImage)))
- {
- return FALSE;
- }
- // 得到图片信息
- if(FAILED(hr = m_pImage->GetImageInfo(&m_ImageInfo)))
- {
- return FALSE;
- }
- // 成功获得图片信息
- return TRUE;
- }
- // 从IImage对象中加载
- BOOL CWFBitmap::LoadFromIImage(
- IImage *pIImage // IImage对象
- )
- {
- // 释放上次图片数据
- Release();
- // 参数有效性
- if (pIImage == NULL)
- {
- return FALSE;
- }
- // 得到IImage对象
- HRESULT hr = pIImage->QueryInterface(IID_IImage, (void **)&m_pImage);
- if (FAILED(hr))
- {
- return FALSE;
- }
- // 得到图片信息
- if(FAILED(hr = m_pImage->GetImageInfo(&m_ImageInfo)))
- {
- return FALSE;
- }
- // 加载成功
- return TRUE;
- }
- // 从IBitmapImage对象中加载
- BOOL CWFBitmap::LoadFromIBitmapImage(
- IBitmapImage *pBitmapImage // IBitmapImage对象
- )
- {
- // 释放上次数据
- Release();
- // 参数有效性
- if (pBitmapImage == NULL)
- {
- return FALSE;
- }
- // 拷贝到新的IBitmapImage对象
- if (CopyBitmapImage(pBitmapImage, m_pBitmapImage) == FALSE)
- {
- return FALSE;
- }
- // 得到新的IImage
- m_pBitmapImage->QueryInterface(IID_IImage, (void**)&m_pImage);
- // 得到新的ImageInfo
- if (m_pImage != NULL)
- {
- m_pImage->GetImageInfo(&m_ImageInfo);
- }
- // 成功
- return TRUE;
- }
- // 释放占用的资源
- void CWFBitmap::Release(void)
- {
- // 释放DC
- DeleteImgDC();
- // 释放原始数据空间
- DeleteImgDateBuf();
- // 释放IMAGE
- if(m_pImage != NULL)
- {
- m_pImage->Release();
- m_pImage = NULL;
- }
- // 释放IBitmapImage
- if (m_pBitmapImage != NULL)
- {
- m_pBitmapImage->Release();
- m_pBitmapImage = NULL;
- }
- }
- // 绘制整个图像到指定位置(会把图像压缩或拉伸填充到指定区域)
- void CWFBitmap::Draw(
- HDC hdc, // 绘制DC
- const RECT* dstRect // 绘制目标区域
- )
- {
- // 获取图像信息失败
- if (m_pImage==NULL || dstRect==NULL)
- {
- return;
- }
- // 绘制图像
- m_pImage->Draw(hdc, dstRect, NULL);
- }
- // 绘制图像上一部分到指定的部分(先绘制到内存DC,再绘制到目标DC)
- void CWFBitmap::Draw(
- HDC hdc, // 绘制DC
- const RECT* dstRect, // 绘制目标区域
- const RECT* srcRect // 待绘制图片上的指定区域,NULL表示整个图片
- )
- {
- // 获取图像信息失败,目标绘图区为NULL
- if (m_pImage==NULL || dstRect==NULL)
- {
- return;
- }
- // 创建内存DC
- if (m_hDrawDC == NULL)
- {
- m_hDrawDC = CreateImgDC(hdc);
- }
- // 把内存DC上指定的部分拷贝到目标DC上
- if (srcRect != NULL)
- {
- ::StretchBlt(hdc,
- dstRect->left,
- dstRect->top,
- dstRect->right-dstRect->left,
- dstRect->bottom-dstRect->top,
- m_hDrawDC,
- srcRect->left,
- srcRect->top,
- srcRect->right-srcRect->left,
- srcRect->bottom-srcRect->top,
- SRCCOPY
- );
- }
- else
- {
- ::BitBlt(hdc,
- dstRect->left,
- dstRect->top,
- dstRect->right-dstRect->left,
- dstRect->bottom-dstRect->top,
- m_hDrawDC,
- 0,
- 0,
- SRCCOPY
- );
- }
- }
- // 绘制图像上一部分到指定的区域(支持alpha混合)
- void CWFBitmap::DrawAlpha(
- HDC hdc, // 绘制DC
- const RECT* dstRect, // 绘制目标区域
- const RECT* srcRect // 待绘制图片上的指定区域,NULL表示整个图片
- )
- {
- // 获取图像信息失败,目标绘图区为NULL
- if (m_pImage==NULL || dstRect==NULL)
- {
- return;
- }
- // 获取原始数据失败
- if (CreateImgDateBuf() == FALSE)
- {
- return;
- }
- // 计算目标区域宽度及高度
- int nDstWidth = dstRect->right - dstRect->left;
- int nDstHeight = dstRect->bottom - dstRect->top;
- // 创建目标绘制区域大小的内存DC
- HDC hDIBDC = CreateCompatibleDC(hdc);
- BITMAPINFO hdr;
- ZeroMemory(&hdr , sizeof(BITMAPINFO));
- hdr.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
- hdr.bmiHeader.biWidth = nDstWidth;
- hdr.bmiHeader.biHeight = -nDstHeight;
- hdr.bmiHeader.biPlanes = 1;
- hdr.bmiHeader.biBitCount = 32;
- BYTE * pbtPixels = NULL;
- HBITMAP hDIBitmap = CreateDIBSection(hDIBDC, (BITMAPINFO *)&hdr, DIB_RGB_COLORS, (void **)&pbtPixels, NULL, 0);
- HBITMAP hOldBmp = (HBITMAP)SelectObject(hDIBDC, hDIBitmap);
- // 拷贝背景DC上目标绘制区域到内存DC
- ::StretchBlt(hDIBDC, 0, 0, nDstWidth, nDstHeight, hdc, dstRect->left, dstRect->top, nDstWidth, nDstHeight, SRCCOPY);
- // 计算使用图片上的源区域大小
- RECT rcImgSrc;
- if (srcRect != NULL)
- {
- rcImgSrc = *srcRect;
- }
- else
- {
- rcImgSrc.left = 0;
- rcImgSrc.top = 0;
- rcImgSrc.right = m_ImageInfo.Width;
- rcImgSrc.bottom = m_ImageInfo.Height;
- }
- // 计算实际使用区域的宽度和高度
- int nUseWidth = (nDstWidth < rcImgSrc.right-rcImgSrc.left) ? nDstWidth : rcImgSrc.right-rcImgSrc.left;
- int nUseHeight = (nDstHeight < rcImgSrc.bottom-rcImgSrc.top) ? nDstHeight : rcImgSrc.bottom-rcImgSrc.top;
- // 进行Alpha混合运算
- BYTE btAlphaSRC = 0;
- int iSrcPos = 0;
- int iDstPos = 0;
- for(int i=0; i<nUseHeight; i++)
- {
- for(int j=0; j<nUseWidth; j++)
- {
- // 计算源及目标索引及该点ALPHA值
- iSrcPos = (i*m_ImageInfo.Width + rcImgSrc.left + j) * 4;
- iDstPos = (i*nDstWidth + j) * 4;
- btAlphaSRC = m_pImgDataBuf[iSrcPos+3];
- // 计算目标像素值,ALPHA混合result = ALPHA * srcPixel + ( 1 - ALPHA ) * destPixel
- pbtPixels[iDstPos] = ((255-btAlphaSRC)*pbtPixels[iDstPos] + btAlphaSRC*m_pImgDataBuf[iSrcPos])/255;
- pbtPixels[iDstPos+1] = ((255-btAlphaSRC)*pbtPixels[iDstPos+1] + btAlphaSRC*m_pImgDataBuf[iSrcPos+1])/255;
- pbtPixels[iDstPos+2] = ((255-btAlphaSRC)*pbtPixels[iDstPos+2] + btAlphaSRC*m_pImgDataBuf[iSrcPos+2])/255;
- }
- }
- // 混合ALPHA后的内存DC拷贝到目标DC
- BitBlt(hdc, dstRect->left, dstRect->top, nDstWidth, nDstHeight, hDIBDC, 0, 0, SRCCOPY);
- // 释放临时内存DC
- SelectObject(hDIBDC, hOldBmp);
- DeleteObject(hDIBDC);
- DeleteObject(hDIBitmap);
- }
- // 绘制整个图像到自定义矩形类型区域(会把图像压缩或拉伸填充到指定区域)
- void CWFBitmap::DrawEx(
- HDC hdc, // 绘制DC
- const CWFRect* dstRect // 绘制目标区域
- )
- {
- // 参数有效性
- if (dstRect == NULL)
- {
- return;
- }
- // 转换矩形区域
- RECT rcDst = {dstRect->x, dstRect->y, dstRect->x+dstRect->w, dstRect->y+dstRect->h};
- Draw(hdc, &rcDst);
- }
- // 绘制图像上一部分到指定的自定义矩形类型区域(先绘制到内存DC,再绘制到目标DC)
- void CWFBitmap::DrawEx(
- HDC hdc, // 绘制DC
- const CWFRect* dstRect, // 绘制目标区域
- const CWFRect* srcRect // 待绘制图片上的指定区域,NULL表示整个图片
- )
- {
- // 参数有效性
- if (dstRect == NULL)
- {
- return;
- }
- // 转换得到目标矩形区域
- RECT rcDst = {dstRect->x, dstRect->y, dstRect->x+dstRect->w, dstRect->y+dstRect->h};
- // 转换得到源矩形区域
- RECT rcSrc = {0};
- if (srcRect != NULL)
- {
- rcSrc.left = srcRect->x;
- rcSrc.top = srcRect->y;
- rcSrc.right = srcRect->x + srcRect->w;
- rcSrc.bottom = srcRect->y + srcRect->h;
- }
- Draw(hdc, &rcDst, (srcRect==NULL) ? NULL : &rcSrc);
- }
- // 绘制图像上一部分到指定的自定义矩形类型区域(支持alpha混合)
- void CWFBitmap::DrawAlphaEx(
- HDC hdc, // 绘制DC
- const CWFRect* dstRect, // 绘制目标区域
- const CWFRect* srcRect // 待绘制图片上的指定区域,NULL表示整个图片
- )
- {
- // 参数有效性
- if (dstRect == NULL)
- {
- return;
- }
- // 转换得到目标矩形区域
- RECT rcDst = {dstRect->x, dstRect->y, dstRect->x+dstRect->w, dstRect->y+dstRect->h};
- // 转换得到源矩形区域
- RECT rcSrc = {0};
- if (srcRect != NULL)
- {
- rcSrc.left = srcRect->x;
- rcSrc.top = srcRect->y;
- rcSrc.right = srcRect->x + srcRect->w;
- rcSrc.bottom = srcRect->y + srcRect->h;
- }
- DrawAlpha(hdc, &rcDst, (srcRect==NULL) ? NULL : &rcSrc);
- }
- // 获得图像的宽度,未加载到图片返回0
- DWORD CWFBitmap::Width() const
- {
- return m_ImageInfo.Width;
- }
- // 获得图像的高度,未加载到图片返回0
- DWORD CWFBitmap::Height() const
- {
- return m_ImageInfo.Height;
- }
- BOOL CWFBitmap::ZoomToIImage(
- PWFIImage &pDstIImage, // 存放缩放后图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放
- DWORD dwNewWidth, // 缩放后图像宽度
- DWORD dwNewHeight // 缩放后图像高度
- )
- {
- // 释放目标IImage对象
- if (pDstIImage != NULL)
- {
- pDstIImage->Release();
- pDstIImage = NULL;
- }
- // 参数有效性
- if (dwNewWidth==0 || dwNewHeight==0 || m_pImage==NULL || m_pImagingFactory==NULL)
- {
- return FALSE;
- }
- // 使用到的临时变量,由于后面使用了goto在此处定义
- BOOL bRet = TRUE; // 函数返回值
- IBitmapImage *pBmp = NULL; // 位图接口
- IBitmapImage *pNewBmp = NULL; // 缩放后位图接口
- IBasicBitmapOps *pBmpOps = NULL; // 位图操作接口
- // 得到位图接口
- HRESULT hr = m_pImagingFactory->CreateBitmapFromImage(m_pImage, m_ImageInfo.Width, m_ImageInfo.Height, m_ImageInfo.PixelFormat, InterpolationHintDefault, &pBmp);
- if (FAILED(hr))
- {
- printf("ZoomToIImage CreateBitmapFromImage Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 得到位图操作接口
- hr = pBmp->QueryInterface(IID_IBasicBitmapOps,(void **)&pBmpOps);
- if (FAILED(hr))
- {
- printf("ZoomToIImage QueryInterface IID_IBasicBitmapOps Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 缩放位图
- hr = pBmpOps->Resize(dwNewWidth, dwNewHeight, m_ImageInfo.PixelFormat, InterpolationHintDefault, &pNewBmp);
- if (FAILED(hr))
- {
- printf("ZoomToIImage Resize Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 得到新IImage
- hr = pNewBmp->QueryInterface(IID_IImage,(void **)&pDstIImage);
- if (FAILED(hr))
- {
- printf("ZoomToIImage QueryInterface pDstIImage Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 正确得到缩放后的IImage
- bRet = TRUE;
- // 进入释放过程
- ERROR_END_FUNCTIONFLAG:
- // 释放位图
- if (pBmp != NULL)
- {
- pBmp->Release();
- pBmp = NULL;
- }
- // 释放缩放后位图
- if (pNewBmp != NULL)
- {
- pNewBmp->Release();
- pNewBmp = NULL;
- }
- // 释放位图操作接口
- if (pBmpOps != NULL)
- {
- pBmpOps->Release();
- pBmpOps = NULL;
- }
- // 返回结果
- return bRet;
- }
- // 缩放图像(指定缩放后图像的宽度和高度)
- BOOL CWFBitmap::Zoom(
- DWORD dwNewWidth, // 缩放后图像宽度
- DWORD dwNewHeight // 缩放后图像高度
- )
- {
- // 缩放后新IImage
- IImage *pNewImage = NULL;
- if (ZoomToIImage(pNewImage, dwNewWidth, dwNewHeight) == FALSE)
- {
- return FALSE;
- }
- // 是否得到缩放后的IImage
- BOOL bRet = (pNewImage!=NULL) ? TRUE : FALSE;
- // 改变IImage对象内容
- if (pNewImage != NULL)
- {
- // 释放原有的IImage
- Release();
- // 得到新的IImage
- m_pImage = pNewImage;
- // 得到新的ImageInfo
- m_pImage->GetImageInfo(&m_ImageInfo);
- }
- // 返回结果
- return bRet;
- }
- // 缩放图像到目标对象中(指定缩放后图像的宽度和高度),不改变对象自身
- BOOL CWFBitmap::Zoom(
- CWFBitmap &dstBitmap, // 带出缩放后的图像
- DWORD dwNewWidth, // 缩放后图像宽度
- DWORD dwNewHeight // 缩放后图像高度
- )
- {
- // 缩放后新IImage
- IImage *pNewImage = NULL;
- if (ZoomToIImage(pNewImage, dwNewWidth, dwNewHeight) == FALSE)
- {
- return FALSE;
- }
- // 通过IImage对象加载
- BOOL bRet = dstBitmap.LoadFromIImage(pNewImage);
- // 释放缩放后对象
- if (pNewImage != NULL)
- {
- pNewImage->Release();
- pNewImage = NULL;
- }
- // 返回缩放结果
- return bRet;
- }
- // 缩放图像(指定缩放X方向,Y方向缩放比率)
- BOOL CWFBitmap::ZoomEx(
- double dbZoomXRatio, // X方向缩放率
- double dbZoomYRatio // Y方向缩放率
- )
- {
- // 计算缩放后图像宽度高度
- DWORD dwNewW = (DWORD)((double)m_ImageInfo.Width * dbZoomXRatio);
- DWORD dwNewH = (DWORD)((double)m_ImageInfo.Height * dbZoomYRatio);
- return Zoom(dwNewW, dwNewH);
- }
- // 缩放图像到目标对象中(指定缩放X方向,Y方向缩放比率),不改变对象自身
- BOOL CWFBitmap::ZoomEx(
- CWFBitmap &dstBitmap, // 带出缩放后的图像
- double dbZoomXRatio, // X方向缩放率
- double dbZoomYRatio // Y方向缩放率
- )
- {
- // 计算缩放后图像宽度高度
- DWORD dwNewW = (DWORD)((double)m_ImageInfo.Width * dbZoomXRatio);
- DWORD dwNewH = (DWORD)((double)m_ImageInfo.Height * dbZoomYRatio);
- return Zoom(dstBitmap, dwNewW, dwNewH);
- }
- // 按特定角度旋转图像到IImage对象中,不改变自身数据
- // 顺时针旋转,只支持90, 180, 270, or 360
- BOOL CWFBitmap::RotateSpecificAngleToIImage(
- PWFIImage &pDstIImage, // 存放旋转后图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放
- float fSpecificAngle // 特定旋转角度(单位:度)
- )
- {
- // 释放目标IImage对象
- if (pDstIImage != NULL)
- {
- pDstIImage->Release();
- pDstIImage = NULL;
- }
- // 参数有效性
- if (m_pImage==NULL || m_pImagingFactory==NULL)
- {
- return FALSE;
- }
- // 使用到的临时变量,由于后面使用了goto在此处定义
- BOOL bRet = TRUE; // 函数返回值
- IBitmapImage *pBmp = NULL; // 位图接口
- IBitmapImage *pNewBmp = NULL; // 缩放后位图接口
- IBasicBitmapOps *pBmpOps = NULL; // 位图操作接口
- // 得到位图接口
- HRESULT hr = m_pImagingFactory->CreateBitmapFromImage(m_pImage, m_ImageInfo.Width, m_ImageInfo.Height, m_ImageInfo.PixelFormat, InterpolationHintDefault, &pBmp);
- if (FAILED(hr))
- {
- printf("RotateSpecificAngleToIImage CreateBitmapFromImage Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 得到位图操作接口
- hr = pBmp->QueryInterface(IID_IBasicBitmapOps,(void **)&pBmpOps);
- if (FAILED(hr))
- {
- printf("RotateSpecificAngleToIImage QueryInterface IID_IBasicBitmapOps Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 旋转位图
- hr = pBmpOps->Rotate(fSpecificAngle, InterpolationHintDefault, &pNewBmp);
- if (FAILED(hr))
- {
- printf("RotateSpecificAngleToIImage Rotate Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 得到新IImage
- hr = pNewBmp->QueryInterface(IID_IImage,(void **)&pDstIImage);
- if (FAILED(hr))
- {
- printf("RotateSpecificAngleToIImage QueryInterface pDstIImage Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 正确得到旋转后的IImage
- bRet = TRUE;
- // 进入释放过程
- ERROR_END_FUNCTIONFLAG:
- // 释放位图
- if (pBmp != NULL)
- {
- pBmp->Release();
- pBmp = NULL;
- }
- // 释放缩放后位图
- if (pNewBmp != NULL)
- {
- pNewBmp->Release();
- pNewBmp = NULL;
- }
- // 释放位图操作接口
- if (pBmpOps != NULL)
- {
- pBmpOps->Release();
- pBmpOps = NULL;
- }
- // 返回结果
- return bRet;
- }
- // 按特定角度旋转图像
- // 顺时针旋转,只支持90, 180, 270, or 360
- BOOL CWFBitmap::RotateSpecificAngle(
- float fSpecificAngle // 特定旋转角度(单位:度)
- )
- {
- // 旋转后新IImage
- IImage *pNewImage = NULL;
- if (RotateSpecificAngleToIImage(pNewImage, fSpecificAngle) == FALSE)
- {
- return FALSE;
- }
- // 是否得到旋转后的IImage
- BOOL bRet = (pNewImage!=NULL) ? TRUE : FALSE;
- // 改变IImage对象内容
- if (pNewImage != NULL)
- {
- // 释放原有的IImage
- Release();
- // 得到新的IImage
- m_pImage = pNewImage;
- // 得到新的ImageInfo
- m_pImage->GetImageInfo(&m_ImageInfo);
- }
- // 返回结果
- return bRet;
- }
- // 按特定角度旋转图像到目标对象中,不改变对象自身
- // 顺时针旋转,只支持90, 180, 270, or 360
- BOOL CWFBitmap::RotateSpecificAngle(
- CWFBitmap &dstBitmap, // 带出旋转后的图像
- float fSpecificAngle // 特定旋转角度(单位:度)
- )
- {
- // 旋转后新IImage
- IImage *pNewImage = NULL;
- if (RotateSpecificAngleToIImage(pNewImage, fSpecificAngle) == FALSE)
- {
- return FALSE;
- }
- // 通过IImage对象加载
- BOOL bRet = dstBitmap.LoadFromIImage(pNewImage);
- // 释放旋转后对象
- if (pNewImage != NULL)
- {
- pNewImage->Release();
- pNewImage = NULL;
- }
- // 返回旋转结果
- return bRet;
- }
- // 翻转图像到IImage对象中,不改变自身数据
- BOOL CWFBitmap::FlipToIImage(
- PWFIImage &pDstIImage, // 存放翻转后图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放
- BOOL bFilpX, // 是否反转X方向
- BOOL bFlipY // 是否反转Y方向
- )
- {
- // 释放目标IImage对象
- if (pDstIImage != NULL)
- {
- pDstIImage->Release();
- pDstIImage = NULL;
- }
- // 参数有效性
- if (m_pImage==NULL || m_pImagingFactory==NULL)
- {
- return FALSE;
- }
- // 使用到的临时变量,由于后面使用了goto在此处定义
- BOOL bRet = TRUE; // 函数返回值
- IBitmapImage *pBmp = NULL; // 位图接口
- IBitmapImage *pNewBmp = NULL; // 缩放后位图接口
- IBasicBitmapOps *pBmpOps = NULL; // 位图操作接口
- // 得到位图接口
- HRESULT hr = m_pImagingFactory->CreateBitmapFromImage(m_pImage, m_ImageInfo.Width, m_ImageInfo.Height, m_ImageInfo.PixelFormat, InterpolationHintDefault, &pBmp);
- if (FAILED(hr))
- {
- printf("FlipToIImage CreateBitmapFromImage Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 得到位图操作接口
- hr = pBmp->QueryInterface(IID_IBasicBitmapOps,(void **)&pBmpOps);
- if (FAILED(hr))
- {
- printf("FlipToIImage QueryInterface IID_IBasicBitmapOps Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 翻转位图
- hr = pBmpOps->Flip(bFilpX, bFlipY, &pNewBmp);
- if (FAILED(hr))
- {
- printf("FlipToIImage Flip Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 得到新IImage
- hr = pNewBmp->QueryInterface(IID_IImage,(void **)&pDstIImage);
- if (FAILED(hr))
- {
- printf("FlipToIImage QueryInterface pDstIImage Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 正确得到翻转后的IImage
- bRet = TRUE;
- // 进入释放过程
- ERROR_END_FUNCTIONFLAG:
- // 释放位图
- if (pBmp != NULL)
- {
- pBmp->Release();
- pBmp = NULL;
- }
- // 释放缩放后位图
- if (pNewBmp != NULL)
- {
- pNewBmp->Release();
- pNewBmp = NULL;
- }
- // 释放位图操作接口
- if (pBmpOps != NULL)
- {
- pBmpOps->Release();
- pBmpOps = NULL;
- }
- // 返回结果
- return bRet;
- }
- // 翻转图像
- BOOL CWFBitmap::Flip(
- BOOL bFilpX, // 是否反转X方向
- BOOL bFlipY // 是否反转Y方向
- )
- {
- // 翻转后新IImage
- IImage *pNewImage = NULL;
- if (FlipToIImage(pNewImage, bFilpX, bFlipY) == FALSE)
- {
- return FALSE;
- }
- // 是否得到翻转后的IImage
- BOOL bRet = (pNewImage!=NULL) ? TRUE : FALSE;
- // 改变IImage对象内容
- if (pNewImage != NULL)
- {
- // 释放原有的IImage
- Release();
- // 得到新的IImage
- m_pImage = pNewImage;
- // 得到新的ImageInfo
- m_pImage->GetImageInfo(&m_ImageInfo);
- }
- // 返回结果
- return bRet;
- }
- // 翻转图像到目标对象中,不改变对象自身
- BOOL CWFBitmap::Flip(
- CWFBitmap &dstBitmap, // 带出翻转后的图像
- BOOL bFilpX, // 是否反转X方向
- BOOL bFlipY // 是否反转Y方向
- )
- {
- // 翻转后新IImage
- IImage *pNewImage = NULL;
- if (FlipToIImage(pNewImage, bFilpX, bFlipY) == FALSE)
- {
- return FALSE;
- }
- // 通过IImage对象加载
- BOOL bRet = dstBitmap.LoadFromIImage(pNewImage);
- // 释放翻转后对象
- if (pNewImage != NULL)
- {
- pNewImage->Release();
- pNewImage = NULL;
- }
- // 返回翻转结果
- return bRet;
- }
- // 裁剪图像上指定区域到IImage对象中,不改变自身数据
- BOOL CWFBitmap::CutToIImage(
- PWFIImage &pDstIImage, // 存放裁剪图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放
- const RECT *pCutRect // 在图像上裁剪的区域
- )
- {
- // 释放目标IImage对象
- if (pDstIImage != NULL)
- {
- pDstIImage->Release();
- pDstIImage = NULL;
- }
- // 参数有效性
- if (m_pImage==NULL || m_pImagingFactory==NULL || pCutRect==NULL)
- {
- return FALSE;
- }
- // 裁剪区域有效性
- if (pCutRect->left>=pCutRect->right || pCutRect->top>=pCutRect->bottom)
- {
- printf("CutToIImage CurRect Error!\n");
- return FALSE;
- }
- // 使用到的临时变量,由于后面使用了goto在此处定义
- BOOL bRet = TRUE; // 函数返回值
- IBitmapImage *pBmp = NULL; // 位图接口
- IBitmapImage *pNewBmp = NULL; // 缩放后位图接口
- IBasicBitmapOps *pBmpOps = NULL; // 位图操作接口
- // 得到位图接口
- HRESULT hr = m_pImagingFactory->CreateBitmapFromImage(m_pImage, m_ImageInfo.Width, m_ImageInfo.Height, m_ImageInfo.PixelFormat, InterpolationHintDefault, &pBmp);
- if (FAILED(hr))
- {
- printf("CutToIImage CreateBitmapFromImage Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 得到位图操作接口
- hr = pBmp->QueryInterface(IID_IBasicBitmapOps,(void **)&pBmpOps);
- if (FAILED(hr))
- {
- printf("CutToIImage QueryInterface IID_IBasicBitmapOps Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 翻转位图
- hr = pBmpOps->Clone(pCutRect, &pNewBmp, TRUE);
- if (FAILED(hr))
- {
- printf("CutToIImage Clone Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 得到新IImage
- hr = pNewBmp->QueryInterface(IID_IImage,(void **)&pDstIImage);
- if (FAILED(hr))
- {
- printf("CutToIImage QueryInterface pDstIImage Error!\n");
- bRet = FALSE;
- goto ERROR_END_FUNCTIONFLAG;
- }
- // 正确得到裁剪的IImage
- bRet = TRUE;
- // 进入释放过程
- ERROR_END_FUNCTIONFLAG:
- // 释放位图
- if (pBmp != NULL)
- {
- pBmp->Release();
- pBmp = NULL;
- }
- // 释放缩放后位图
- if (pNewBmp != NULL)
- {
- pNewBmp->Release();
- pNewBmp = NULL;
- }
- // 释放位图操作接口
- if (pBmpOps != NULL)
- {
- pBmpOps->Release();
- pBmpOps = NULL;
- }
- // 返回结果
- return bRet;
- }
- // 裁剪图像(图像改变为指定裁剪区域的图像)
- BOOL CWFBitmap::Cut(
- const RECT *pCutRect // 在图像上裁剪的区域
- )
- {
- // 裁剪到的新IImage
- IImage *pNewImage = NULL;
- if (CutToIImage(pNewImage, pCutRect) == FALSE)
- {
- return FALSE;
- }
- // 是否得到裁剪的IImage
- BOOL bRet = (pNewImage!=NULL) ? TRUE : FALSE;
- // 改变IImage对象内容
- if (pNewImage != NULL)
- {
- // 释放原有的IImage
- Release();
- // 得到新的IImage
- m_pImage = pNewImage;
- // 得到新的ImageInfo
- m_pImage->GetImageInfo(&m_ImageInfo);
- }
- // 返回结果
- return bRet;
- }
- // 裁剪图像到目标对象中,不改变对象自身
- BOOL CWFBitmap::Cut(
- CWFBitmap &dstBitmap, // 带出裁剪到的图像
- const RECT *pCutRect // 在图像上裁剪的区域
- )
- {
- // 裁剪到的IImage
- IImage *pNewImage = NULL;
- if (CutToIImage(pNewImage, pCutRect) == FALSE)
- {
- return FALSE;
- }
- // 通过IImage对象加载
- BOOL bRet = dstBitmap.LoadFromIImage(pNewImage);
- // 释放新的对象
- if (pNewImage != NULL)
- {
- pNewImage->Release();
- pNewImage = NULL;
- }
- // 返回结果
- return bRet;
- }
- // 生成缩略图到指定IImage对象中,不改变自身数据
- BOOL CWFBitmap::ThumbnailToIImage(
- PWFIImage &pDstIImage, // 存放缩略图的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放
- DWORD dwThumbWidth, // 缩略图宽度
- DWORD dwThumbHeight // 缩略图高度
- )
- {
- // 释放目标IImage对象
- if (pDstIImage != NULL)
- {
- pDstIImage->Release();
- pDstIImage = NULL;
- }
- // 参数有效性
- if (m_pImage==NULL || dwThumbWidth==0 || dwThumbHeight==0)
- {
- return FALSE;
- }
- // 得到缩略图
- HRESULT hr = m_pImage->GetThumbnail(dwThumbWidth, dwThumbHeight, &pDstIImage);
- if (FAILED(hr))
- {
- printf("ThumbnailToIImage GetThumbnail Error!\n");
- return FALSE;
- }
- // 得到缩略图
- return TRUE;
- }
- // 生成缩略图(图像改变为缩略图)
- BOOL CWFBitmap::Thumbnail(
- DWORD dwThumbWidth, // 缩略图宽度
- DWORD dwThumbHeight // 缩略图高度
- )
- {
- // 得到新的IImage
- IImage *pNewImage = NULL;
- if (ThumbnailToIImage(pNewImage, dwThumbWidth, dwThumbHeight) == FALSE)
- {
- return FALSE;
- }
- // 是否得到新的IImage
- BOOL bRet = (pNewImage!=NULL) ? TRUE : FALSE;
- // 改变IImage对象内容
- if (pNewImage != NULL)
- {
- // 释放原有的IImage
- Release();
- // 得到新的IImage
- m_pImage = pNewImage;
- // 得到新的ImageInfo
- m_pImage->GetImageInfo(&m_ImageInfo);
- }
- // 返回结果
- return bRet;
- }
- // 生成缩略图(指定缩放比率)(图像改变为缩略图)
- BOOL CWFBitmap::ThumbnailEx(
- double dbXRatio, // X方向缩放率
- double dbYRatio // Y方向缩放率
- )
- {
- // 计算缩放后图像宽度高度
- DWORD dwNewW = (DWORD)((double)m_ImageInfo.Width * dbXRatio);
- DWORD dwNewH = (DWORD)((double)m_ImageInfo.Height * dbYRatio);
- return Thumbnail(dwNewW, dwNewH);
- }
- // 生成缩略图到目标对象中,不改变对象自身
- BOOL CWFBitmap::Thumbnail(
- CWFBitmap &dstBitmap, // 带出旋转后的图像
- DWORD dwThumbWidth, // 缩略图宽度
- DWORD dwThumbHeight // 缩略图高度
- )
- {
- // 得到新的IImage
- IImage *pNewImage = NULL;
- if (ThumbnailToIImage(pNewImage, dwThumbWidth, dwThumbHeight) == FALSE)
- {
- return FALSE;
- }
- // 通过IImage对象加载
- BOOL bRet = dstBitmap.LoadFromIImage(pNewImage);
- // 释放新的对象
- if (pNewImage != NULL)
- {
- pNewImage->Release();
- pNewImage = NULL;
- }
- // 返回结果
- return bRet;
- }
- // 生成缩略图到目标对象中(指定缩放比率),不改变对象自身
- BOOL CWFBitmap::ThumbnailEx(
- CWFBitmap &dstBitmap, // 带出旋转后的图像
- double dbXRatio, // X方向缩放率
- double dbYRatio // Y方向缩放率
- )
- {
- // 计算缩放后图像宽度高度
- DWORD dwNewW = (DWORD)((double)m_ImageInfo.Width * dbXRatio);
- DWORD dwNewH = (DWORD)((double)m_ImageInfo.Height * dbYRatio);
- return Thumbnail(dstBitmap, dwNewW, dwNewH);
- }
- // 图像旋转任意角度到IBitmapImage对象中,不改变自身数据
- // 若只需要旋转90,180,270,360请调用接口RotateSpecificAngleToIImage
- BOOL CWFBitmap::RotateToIBitmapImage(
- PWFIBitmapImage &pDstIBitmapImage, // 存放旋转后图像的IBitmapImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放
- float fAngle // 特定旋转角度(单位:度)
- )
- {
- // 释放目标IImage对象
- if (pDstIBitmapImage != NULL)
- {
- pDstIBitmapImage->Release();
- pDstIBitmapImage = NULL;
- }
- // 参数有效性
- if (m_pImage==NULL || m_pImagingFactory==NULL)
- {
- return FALSE;
- }
- // 得到图片数据区
- if (CreateImgDateBuf() == FALSE)
- {
- return FALSE;
- }
- // 旋转图像数据缓冲区
- PWFBYTE pDstBuf = NULL;
- DWORD dwDstWidth = 0;
- DWORD dwDstHeight = 0;
- if (WFBING_RotateImageBuffer(
- m_pImgDataBuf,
- m_ImageInfo.Width,
- m_ImageInfo.Height,
- (double)fAngle,
- pDstBuf,
- dwDstWidth,
- dwDstHeight
- ) == FALSE)
- {
- return FALSE;
- }
- // 由于CreateBitmapFromBuffer创建时需要自己管理内存,对于CWFBitmap对象间的赋值拷贝不容易处理
- // 此处使用CreateNewBitmap创建新的位图,把得到旋转后的数据强制写入,管理此IBitmapImage即可
- // 用于锁定位图数据
- BitmapData bitmapData;
- bitmapData.Width = dwDstWidth;
- bitmapData.Height = dwDstHeight;
- bitmapData.PixelFormat = PIXFMT_32BPP_ARGB;
- RECT rect = {0, 0, dwDstWidth, dwDstHeight};
- // 创建新的位图
- HRESULT hr = m_pImagingFactory->CreateNewBitmap(dwDstWidth, dwDstHeight, PIXFMT_32BPP_ARGB, &pDstIBitmapImage);
- BOOL bRet = FALSE;
- if (FAILED(hr))
- {
- bRet = FALSE;
- goto THEEND_FOR_THISFOUNCTION;
- }
- // 锁定位图数据
- hr = pDstIBitmapImage->LockBits(&rect, ImageLockModeRead, PIXFMT_32BPP_ARGB, &bitmapData);
- if (FAILED(hr))
- {
- bRet = FALSE;
- goto THEEND_FOR_THISFOUNCTION;
- }
- // 把旋转后数据写入位图
- BYTE *pBmpBuf = (BYTE*)bitmapData.Scan0;
- memcpy(pBmpBuf, pDstBuf, dwDstWidth*dwDstHeight*4);
- // 释放锁定位图数据
- pDstIBitmapImage->UnlockBits(&bitmapData);
- // 写入成功
- bRet = TRUE;
- THEEND_FOR_THISFOUNCTION:
- // 释放临时存放旋转后
- if (pDstBuf != NULL)
- {
- delete[] pDstBuf;
- pDstBuf = NULL;
- }
- // 释放IBitmapImage对象
- if (bRet==FALSE && pDstIBitmapImage!=NULL)
- {
- pDstIBitmapImage->Release();
- pDstIBitmapImage = NULL;
- }
- // 返回结果
- return bRet;
- }
- // 按任意角度旋转图像
- // 若只需要旋转90,180,270,360请调用接口RotateSpecificAngle
- BOOL CWFBitmap::Rotate(
- float fAngle // 特定旋转角度(单位:度)
- )
- {
- // 得到新的IBitmapImage
- IBitmapImage *pNewBitmapImage = NULL;
- if (RotateToIBitmapImage(pNewBitmapImage, fAngle) == FALSE)
- {
- return FALSE;
- }
- // 是否得到新的IImage
- BOOL bRet = (pNewBitmapImage!=NULL) ? TRUE : FALSE;
- // 改变IImage对象内容
- if (pNewBitmapImage != NULL)
- {
- // 释放原有的IImage
- Release();
- // 得到IBitmapImage
- m_pBitmapImage = pNewBitmapImage;
- // 得到新的IImage
- m_pBitmapImage->QueryInterface(IID_IImage, (void**)&m_pImage);
- // 得到新的ImageInfo
- if (m_pImage != NULL)
- {
- m_pImage->GetImageInfo(&m_ImageInfo);
- }
- }
- // 返回结果
- return bRet;
- }
- // 按任意角度旋转图像到目标对象中,不改变对象自身
- // 若只需要旋转90,180,270,360请调用接口RotateSpecificAngle
- BOOL CWFBitmap::Rotate(
- CWFBitmap &dstBitmap, // 带出旋转后的图像
- float fAngle // 特定旋转角度(单位:度)
- )
- {
- // 得到新的IBitmapImage
- IBitmapImage *pNewBitmapImage = NULL;
- if (RotateToIBitmapImage(pNewBitmapImage, fAngle) == FALSE)
- {
- return FALSE;
- }
- // 通过IImage对象加载
- BOOL bRet = dstBitmap.LoadFromIBitmapImage(pNewBitmapImage);
- // 释放新的对象
- if (pNewBitmapImage != NULL)
- {
- pNewBitmapImage->Release();
- pNewBitmapImage = NULL;
- }
- // 返回结果
- return bRet;
- }
- // 获得图像数据(只含有各个点的颜色信息)
- BOOL CWFBitmap::GetColorBuf(
- unsigned char *pDataBuf, // 存放图像数据缓冲区
- DWORD dwcbBufSize, // 缓冲区实际大小(需要的大小通常是(宽度*高度*4))
- DWORD *pdwRealGetBytes // 实际取得数据字节大小
- )
- {
- // 参数有效性
- if (pDataBuf==NULL || dwcbBufSize==0)
- {
- return FALSE;
- }
- // 获取原始数据失败
- if (CreateImgDateBuf() == FALSE)
- {
- return FALSE;
- }
- // 计算实际取得数据字节大小
- DWORD dwRealBytes = (dwcbBufSize < m_dwcbImgDataBufSize) ? dwcbBufSize : m_dwcbImgDataBufSize;
- if (dwRealBytes == 0)
- {
- return FALSE;
- }
- // 拷贝数据
- memcpy(pDataBuf, m_pImgDataBuf, dwRealBytes);
- // 带出实际拷贝数据字节数
- if (pdwRealGetBytes != NULL)
- {
- *pdwRealGetBytes = dwRealBytes;
- }
- // 取得数据成功
- return TRUE;
- }
- // 获得图片数据(只含有各个点的颜色信息)缓冲区地址,返回NULL表示没有图片数据
- const unsigned char* CWFBitmap::GetColorBufAddr(
- DWORD *pdwcbBufSize // 带出颜色缓冲区字节大小
- )
- {
- // 初始化输出参数
- if (pdwcbBufSize != NULL)
- {
- *pdwcbBufSize = 0;
- }
- // 获取原始数据失败
- if (CreateImgDateBuf() == FALSE)
- {
- return NULL;
- }
- // 带出实际大小
- if (pdwcbBufSize != NULL)
- {
- *pdwcbBufSize = m_dwcbImgDataBufSize;
- }
- // 返回地址
- return m_pImgDataBuf;
- }
- //
- // 创建Image工厂接口对象
- BOOL CWFBitmap::CreateImagingFactory(void)
- {
- // 已经创建了Image工厂接口对象
- if (m_pImagingFactory != NULL)
- {
- m_dwObjCounts += 1;
- return TRUE;
- }
- // 未创建则创建Image工厂接口对象
- m_dwObjCounts = 0;
- // COM初始化
- HRESULT hr = NULL;
- if (FAILED(hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED)))
- {
- return FALSE;
- }
- // 创建COM实例
- if(FAILED(hr = ::CoCreateInstance(CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void**)&m_pImagingFactory)))
- {
- return FALSE;
- }
- // 创建成功数量增加
- m_dwObjCounts += 1;
- return TRUE;
- }
- // 释放Image工厂接口对象
- void CWFBitmap::DeleteImagingFactory(void)
- {
- if (m_pImagingFactory!=NULL && m_dwObjCounts>0)
- {
- m_dwObjCounts -= 1;
- if (m_dwObjCounts == 0)
- {
- // 释放ImagingFactory
- m_pImagingFactory->Release();
- m_pImagingFactory = NULL;
- // 释放COM
- ::CoUninitialize();
- }
- }
- }
- // 为图片创建内存DC
- HDC CWFBitmap::CreateImgDC(HDC hdc)
- {
- if (m_hDrawDC != NULL)
- {
- return m_hDrawDC;
- }
- // 创建内存DC
- m_hDrawDC = ::CreateCompatibleDC(hdc);
- m_hBitmap = ::CreateCompatibleBitmap(hdc, m_ImageInfo.Width, m_ImageInfo.Height);
- m_hOldBitmap = (HBITMAP)::SelectObject(m_hDrawDC, m_hBitmap);
- // 填充背景为全黑色
- ::PatBlt(m_hDrawDC, 0, 0, m_ImageInfo.Width, m_ImageInfo.Height, BLACKNESS);
- // 绘制图像到内存DC上
- RECT rcDc = {0, 0, m_ImageInfo.Width, m_ImageInfo.Height};
- m_pImage->Draw(m_hDrawDC, &rcDc, NULL);
- return m_hDrawDC;
- }
- // 清除内存DC
- void CWFBitmap::DeleteImgDC(void)
- {
- if (m_hDrawDC != NULL)
- {
- ::SelectObject(m_hDrawDC, m_hOldBitmap);
- ::DeleteObject(m_hBitmap);
- ::DeleteDC(m_hDrawDC);
- m_hDrawDC = NULL;
- m_hBitmap = NULL;
- m_hOldBitmap = NULL;
- }
- }
- // 取得图片原始数据
- BOOL CWFBitmap::CreateImgDateBuf(void)
- {
- // 已经获取到了原始数据
- if (m_pImgDataBuf != NULL)
- {
- return TRUE;
- }
- // 参数有效性
- if (m_pImage==NULL || m_pImagingFactory==NULL)
- {
- return FALSE;
- }
- // 取得图片原始数据
- RECT rect = {0, 0, m_ImageInfo.Width, m_ImageInfo.Height};
- BitmapData bitmapData;
- bitmapData.Width = m_ImageInfo.Width;
- bitmapData.Height = m_ImageInfo.Height;
- bitmapData.PixelFormat = m_ImageInfo.PixelFormat;
- IBitmapImage *pBitmapImage = NULL;
- HRESULT hr = m_pImagingFactory->CreateBitmapFromImage(m_pImage, m_ImageInfo.Width, m_ImageInfo.Height, PIXFMT_32BPP_ARGB, InterpolationHintDefault, &pBitmapImage);
- if (FAILED(hr))
- {
- printf("CreateImgDateBuf CreateBitmapFromImage Error!\n");
- return FALSE;
- }
- // 锁定位图数据
- hr = pBitmapImage->LockBits(&rect, ImageLockModeRead, PIXFMT_32BPP_ARGB, &bitmapData);
- if (FAILED(hr))
- {
- printf("CreateImgDateBuf LockBits Error!\n");
- pBitmapImage->Release();
- return FALSE;
- }
- // 用于返回结果
- BOOL bRet = TRUE;
- // 得到数据字节大小
- m_dwcbImgDataBufSize = m_ImageInfo.Width * m_ImageInfo.Height * 4;
- if (m_dwcbImgDataBufSize == 0)
- {
- bRet = FALSE;
- goto ERROR_END_FUNCTION;
- }
- // 申请新空间
- bRet = TRUE;
- m_pImgDataBuf = new unsigned char[m_dwcbImgDataBufSize];
- if (m_pImgDataBuf == NULL)
- {
- bRet = FALSE;
- goto ERROR_END_FUNCTION;
- }
- // 拷贝数据
- bRet = TRUE;
- memcpy(m_pImgDataBuf, bitmapData.Scan0, m_ImageInfo.Width * m_ImageInfo.Height * 4);
- ERROR_END_FUNCTION:
- pBitmapImage->UnlockBits(&bitmapData);
- pBitmapImage->Release();
- return bRet;
- }
- // 销毁图片原始数据
- void CWFBitmap::DeleteImgDateBuf(void)
- {
- if (m_pImgDataBuf != NULL)
- {
- delete[] m_pImgDataBuf;
- m_pImgDataBuf = NULL;
- m_dwcbImgDataBufSize = 0;
- }
- }
- // 拷贝一个IBitmapImage到另一个IBitmapImage中
- BOOL CWFBitmap::CopyBitmapImage(
- IBitmapImage *pSrcBitmapImage, // 源IBitmapImage
- PWFIBitmapImage &pDstBitmapImage // 目标IBitmapImage
- )
- {
- // 释放目标对象
- if (pDstBitmapImage != NULL)
- {
- pDstBitmapImage->Release();
- pDstBitmapImage = NULL;
- }
- // 参数有效性
- if (pSrcBitmapImage == NULL)
- {
- return FALSE;
- }
- // 得到原图IImage
- IImage *pSrcImage = NULL;
- HRESULT hr = pSrcBitmapImage->QueryInterface(IID_IImage, (void**)&pSrcImage);
- if (FAILED(hr))
- {
- printf("CopyBitmapImage QueryInterface SrcImage Error!\n");
- return FALSE;
- }
- // 使用到的临时变量在此处声明,因为下面需要使用goto语句
- BOOL bRet = FALSE; // 用于返回函数结果
- ImageInfo srcImageInfo; // 存放原图图像信息
- RECT rect; // 用于锁定图像数据时的区域
- BitmapData srcBitmapData; // 用于锁定原图数据
- BOOL bLockedSrcImg = FALSE; // 是否锁定原图
- BitmapData dstBitmapData; // 用于锁定新图像数据
- BOOL bLockedDstImg = FALSE; // 是否锁定新图
- // 得到原图ImageInfo
- hr = pSrcImage->GetImageInfo(&srcImageInfo);
- if (FAILED(hr))
- {
- printf("CopyBitmapImage GetImageInfo srcImageInfo Error!\n");
- bRet = FALSE;
- goto THEEND_FOR_THISFOUNCTION;
- }
- // 锁定原图数据区
- rect.left = 0;
- rect.top = 0;
- rect.right = srcImageInfo.Width;
- rect.bottom = srcImageInfo.Height;
- srcBitmapData.Width = srcImageInfo.Width;
- srcBitmapData.Height = srcImageInfo.Height;
- srcBitmapData.PixelFormat = srcImageInfo.PixelFormat;
- hr = pSrcBitmapImage->LockBits(&rect, ImageLockModeRead, srcImageInfo.PixelFormat, &srcBitmapData);
- bLockedSrcImg = TRUE;
- if (FAILED(hr))
- {
- printf("CopyBitmapImage LockBits srcBitmapData Error!\n");
- bLockedSrcImg = FALSE;
- bRet = FALSE;
- goto THEEND_FOR_THISFOUNCTION;
- }
- //
- // 创建新的位图
- hr = m_pImagingFactory->CreateNewBitmap(srcImageInfo.Width, srcImageInfo.Height, PIXFMT_32BPP_ARGB, &pDstBitmapImage);
- if (FAILED(hr))
- {
- printf("CopyBitmapImage CreateNewBitmap Error!\n");
- bRet = FALSE;
- goto THEEND_FOR_THISFOUNCTION;
- }
- // 锁定新位图数据
- dstBitmapData.Width = srcImageInfo.Width;
- dstBitmapData.Height = srcImageInfo.Height;
- dstBitmapData.PixelFormat = srcImageInfo.PixelFormat;
- hr = pDstBitmapImage->LockBits(&rect, ImageLockModeRead, PIXFMT_32BPP_ARGB, &dstBitmapData);
- bLockedDstImg = TRUE;
- if (FAILED(hr))
- {
- printf("CopyBitmapImage LockBits dstBitmapData Error!\n");
- bLockedDstImg = FALSE;
- bRet = FALSE;
- goto THEEND_FOR_THISFOUNCTION;
- }
- //
- // 把原图数据写人新图
- memcpy((BYTE*)dstBitmapData.Scan0, (BYTE*)srcBitmapData.Scan0, srcImageInfo.Width*srcImageInfo.Height*4);
- bRet = TRUE;
- // 进入资源释放过程
- THEEND_FOR_THISFOUNCTION:
- // 锁定了原图
- if (bLockedSrcImg == TRUE)
- {
- pSrcBitmapImage->UnlockBits(&srcBitmapData);
- }
- // 锁定了新图
- if (bLockedDstImg == TRUE)
- {
- pDstBitmapImage->UnlockBits(&dstBitmapData);
- }
- // 释放原图IImage
- if (pSrcImage != NULL)
- {
- pSrcImage->Release();
- pSrcImage = NULL;
- }
- // 返回结果
- return bRet;
- }
涉及到的矩形类头文件如下:
- /********************************************************************
- Copyright(c) 2011,
- All rights reserved.
- purpose: 矩形类
- 当前版本: 1.0
- 作 者: zhangwf
- 创建日期: 2011:9:6
- 完成日期:
- 取代版本:
- 作 者:
- 完成日期:
- *********************************************************************/
- #ifndef _WF_RECT_H_
- #define _WF_RECT_H_
- //
- class CWFRect
- {
- public: // 成员变量
- long x; // 左上角X坐标
- long y; // 左上角Y坐标
- long w; // 矩形宽度
- long h; // 矩形高度
- public:
- // 构造函数
- CWFRect();
- // 析构函数
- ~CWFRect();
- // 带参构造
- CWFRect(long x, long y, long w, long h);
- // 拷贝构造函数
- CWFRect(const CWFRect &other);
- // 赋值函数
- CWFRect& operator=(const CWFRect &other);
- // 比较是否相等
- bool operator==(const CWFRect &other);
- // 比较是否不等
- bool operator!=(const CWFRect &other);
- // 检查是否被另一个矩形包含
- bool operator<=(const CWFRect &other);
- // 检查是否包含另一个矩形
- bool operator>=(const CWFRect &other);
- // 求矩形交集,没有交集返回CWFRect(0,0,0,0)
- CWFRect operator&(const CWFRect &other);
- // 求矩形交集,没有交集结果为CWFRect(0,0,0,0)
- CWFRect& operator&=(const CWFRect &other);
- // 求并集,返回能够包含此两个矩形的矩形区域
- CWFRect operator|(const CWFRect &other);
- // 求并集,结果为能够包含此两个矩形的矩形区域
- CWFRect& operator|=(const CWFRect &other);
- // 该矩形区域是否包含某点
- bool CheckIn(long x, long y);
- // 检测是否有效(检测矩形宽度和高度不能小于或等于0)
- bool CheckValid(void);
- };
- //
- #endif
涉及到的矩形类实现文件如下:
- /********************************************************************
- Copyright(c) 2011,
- All rights reserved.
- purpose: 矩形类
- 当前版本: 1.0
- 作 者: zhangwf
- 创建日期: 2011:9:6
- 完成日期:
- 取代版本:
- 作 者:
- 完成日期:
- *********************************************************************/
- #include "WFRect.h"
- //
- // 构造函数
- CWFRect::CWFRect()
- : x(0)
- , y(0)
- , w(0)
- , h(0)
- {
- }
- // 析构函数
- CWFRect::~CWFRect()
- {
- }
- // 带参构造
- CWFRect::CWFRect(long x, long y, long w, long h)
- : x(x)
- , y(y)
- , w(w)
- , h(h)
- {
- }
- // 拷贝构造函数
- CWFRect::CWFRect(const CWFRect &other)
- : x(other.x)
- , y(other.y)
- , w(other.w)
- , h(other.h)
- {
- }
- // 赋值函数
- CWFRect& CWFRect::operator=(const CWFRect &other)
- {
- // 检查自赋值
- if (this == &other)
- {
- return *this;
- }
- // 赋值
- x = other.x;
- y = other.y;
- w = other.w;
- h = other.h;
- return *this;
- }
- // 比较是否相等
- bool CWFRect::operator==(const CWFRect &other)
- {
- // 检查是否和自己比较
- if (this == &other)
- {
- return true;
- }
- // 比较是否相等
- return (x==other.x && y==other.y && w==other.w && h==other.h);
- }
- // 比较是否不等
- bool CWFRect::operator!=(const CWFRect &other)
- {
- // 检查是否和自己比较
- if (this == &other)
- {
- return false;
- }
- // 比较是否不等
- return (x!=other.x || y!=other.y || w!=other.w || h!=other.h);
- }
- // 检查是否被另一个矩形包含
- bool CWFRect::operator<=(const CWFRect &other)
- {
- // 检查是否和自己比较
- if (this == &other)
- {
- return true;
- }
- // 比较是否被另一个矩形包含
- return (x>=other.x && (x+w)<=(other.x+other.w) && y>=other.y && (y+h)<=(other.y+other.h));
- }
- // 检查是否包含另一个矩形
- bool CWFRect::operator>=(const CWFRect &other)
- {
- // 检查是否和自己比较
- if (this == &other)
- {
- return true;
- }
- // 比较是否包含另一个矩形
- return (other.x>=x && (other.x+other.w)<=(x+w) && other.y>=y && (other.y+other.h)<=(y+h));
- }
- // 求矩形交集
- CWFRect CWFRect::operator&(const CWFRect &other)
- {
- // 是否和自己求交集
- if (this == &other)
- {
- return *this;
- }
- // 计算相交区域左上角点坐标
- long lTopX = (x >= other.x) ? x : other.x;
- long lTopY = (y >= other.y) ? y : other.y;
- // 计算相交区域有效角点坐标
- long rBtmX = ((x+w) >= (other.x+other.w)) ? (other.x+other.w) : (x+w);
- long rBtmY = ((y+h) >= (other.y+other.h)) ? (other.y+other.h) : (y+h);
- // 返回交集
- return (lTopX>rBtmX || lTopY>rBtmY) ? CWFRect(0,0,0,0) : CWFRect(lTopX, lTopY, rBtmX-lTopX, rBtmY-lTopY);
- }
- // 求矩形交集
- CWFRect& CWFRect::operator&=(const CWFRect &other)
- {
- // 是否和自己求交集
- if (this == &other)
- {
- return *this;
- }
- // 计算相交区域左上角点坐标
- long lTopX = (x >= other.x) ? x : other.x;
- long lTopY = (y >= other.y) ? y : other.y;
- // 计算相交区域有效角点坐标
- long rBtmX = ((x+w) >= (other.x+other.w)) ? (other.x+other.w) : (x+w);
- long rBtmY = ((y+h) >= (other.y+other.h)) ? (other.y+other.h) : (y+h);
- // 计算交集结果
- // 没有交集
- if (lTopX>rBtmX || lTopY>rBtmY)
- {
- x = 0;
- y = 0;
- w = 0;
- h = 0;
- }
- // 具有交集
- else
- {
- x = lTopX;
- y = lTopY;
- w = rBtmX - lTopX;
- h = rBtmY - lTopY;
- }
- // 返回结果
- return *this;
- }
- // 求并集,返回能够包含此两个矩形的矩形区域
- CWFRect CWFRect::operator|(const CWFRect &other)
- {
- // 是否和自己求并集
- if (this == &other)
- {
- return *this;
- }
- // 计算合并区域左上角坐标
- long lTopX = (x <= other.x) ? x : other.x;
- long lTopY = (y <= other.y) ? y : other.y;
- // 计算合并区域右下角坐标
- long rBtmX = ((x+w) <= (other.x+other.w)) ? (other.x+other.w) : (x+w);
- long rBtmY = ((y+h) <= (other.y+other.h)) ? (other.y+other.h) : (y+h);
- // 返回并集
- return CWFRect(lTopX, lTopY, rBtmX-lTopX, rBtmY-lTopY);
- }
- // 求并集,结果为能够包含此两个矩形的矩形区域
- CWFRect& CWFRect::operator|=(const CWFRect &other)
- {
- // 是否和自己求并集
- if (this == &other)
- {
- return *this;
- }
- // 计算合并区域左上角坐标
- long lTopX = (x <= other.x) ? x : other.x;
- long lTopY = (y <= other.y) ? y : other.y;
- // 计算合并区域右下角坐标
- long rBtmX = ((x+w) <= (other.x+other.w)) ? (other.x+other.w) : (x+w);
- long rBtmY = ((y+h) <= (other.y+other.h)) ? (other.y+other.h) : (y+h);
- // 计算并集
- x = lTopX;
- y = lTopY;
- w = rBtmX - lTopX;
- h = rBtmY - lTopY;
- return *this;
- }
- // 该矩形区域是否包含某点
- bool CWFRect::CheckIn(long x, long y)
- {
- return (x>=this->x && x<=(this->x+this->w) && y>=this->y && y<=(this->y+this->h));
- }
- // 检测是否有效(检测矩形宽度和高度不能小于或等于0)
- bool CWFRect::CheckValid(void)
- {
- return (w>0 && h>0);
- }
转载自:http://blog.csdn.net/werocpp/article/details/7435784