wince图片编解码

头文件如下:

  1. /******************************************************************** 
  2.     Copyright(c) 2011,  
  3.     All rights reserved. 
  4.     purpose:    图片加载使用类 
  5.  
  6.     当前版本:   1.0 
  7.     作    者:   zhangwf 
  8.     创建日期:   2011:9:6 
  9.     完成日期:    
  10.      
  11.     取代版本: 
  12.     作    者: 
  13.     完成日期:    
  14. *********************************************************************/  
  15. #ifndef _WF_BITMAP_H_  
  16. #define _WF_BITMAP_H_  
  17. //  
  18. #include <Windows.h>  
  19. #include <imaging.h>  
  20. #include "WFRect.h"  
  21. //  
  22. class CWFBitmap  
  23. {  
  24. public:  
  25.     // 构造函数  
  26.     CWFBitmap();  
  27.   
  28.     // 析构函数  
  29.     ~CWFBitmap();  
  30.   
  31.     // 拷贝构造函数  
  32.     CWFBitmap(const CWFBitmap &other);  
  33.   
  34.     // 赋值函数  
  35.     CWFBitmap& operator=(const CWFBitmap &other);  
  36.   
  37. //  
  38. public// 图像加载释放、图像大小相关接口  
  39.     // 从文件中加载  
  40.     BOOL LoadFromFile(  
  41.         LPCWSTR lpFileName         // 文件绝对路径  
  42.         );  
  43.   
  44.     // 从资源中加载,例如LoadFromResource(MAKEINTRESOURCE(IDR_BACKIMG), _T("PNG"));  
  45.     BOOL LoadFromResource(  
  46.         LPCWSTR lpName,            // 资源名称比如:MAKEINTRESOURCE(IDR_BACKIMG)              
  47.         LPCWSTR lpType             // 资源类型比如:_T("PNG")  
  48.         );  
  49.   
  50.     // 从缓冲区中加载(该缓冲区为整个图像文件数据缓冲区,包括文件头等一切文件信息)  
  51.     BOOL LoadFromBuffer(  
  52.         const unsigned char *pBuf, // 缓冲区地址  
  53.         DWORD dwcbBufSize          // 缓冲区字节大小  
  54.         );  
  55.   
  56.     // 从IImage对象中加载  
  57.     BOOL LoadFromIImage(  
  58.         IImage *pIImage            // IImage对象  
  59.         );  
  60.   
  61.     // 从IBitmapImage对象中加载(内部会生成新的IBitmapImage用于拷贝原数据)  
  62.     BOOL LoadFromIBitmapImage(  
  63.         IBitmapImage *pBitmapImage // IBitmapImage对象   
  64.         );  
  65.   
  66.     // 释放占用的资源  
  67.     void Release(void);  
  68.   
  69.     // 获得图像的宽度,未加载到图片返回0  
  70.     DWORD Width() const;  
  71.   
  72.     // 获得图像的高度,未加载到图片返回0  
  73.     DWORD Height() const;   
  74.   
  75. //  
  76. public// 图像绘制相关接口  
  77.     // 绘制整个图像到指定位置(会把图像压缩或拉伸填充到指定区域)  
  78.     void Draw(  
  79.         HDC hdc,                   // 绘制DC   
  80.         const RECT* dstRect        // 绘制目标区域  
  81.         );    
  82.   
  83.     // 绘制图像上一部分到指定的部分(先绘制到内存DC,再绘制到目标DC)  
  84.     void Draw(  
  85.         HDC hdc,                   // 绘制DC  
  86.         const RECT* dstRect,       // 绘制目标区域  
  87.         const RECT* srcRect        // 待绘制图片上的指定区域,NULL表示整个图片  
  88.         );  
  89.   
  90.     // 绘制图像上一部分到指定的区域(支持alpha混合)  
  91.     void DrawAlpha(  
  92.         HDC hdc,                   // 绘制DC  
  93.         const RECT* dstRect,       // 绘制目标区域  
  94.         const RECT* srcRect        // 待绘制图片上的指定区域,NULL表示整个图片  
  95.         );  
  96.   
  97.     // 绘制整个图像到自定义矩形类型区域(会把图像压缩或拉伸填充到指定区域)  
  98.     void DrawEx(  
  99.         HDC hdc,                   // 绘制DC   
  100.         const CWFRect* dstRect     // 绘制目标区域  
  101.         );  
  102.   
  103.     // 绘制图像上一部分到指定的自定义矩形类型区域(先绘制到内存DC,再绘制到目标DC)  
  104.     void DrawEx(  
  105.         HDC hdc,                   // 绘制DC  
  106.         const CWFRect* dstRect,    // 绘制目标区域  
  107.         const CWFRect* srcRect     // 待绘制图片上的指定区域,NULL表示整个图片  
  108.         );  
  109.   
  110.     // 绘制图像上一部分到指定的自定义矩形类型区域(支持alpha混合)  
  111.     void DrawAlphaEx(  
  112.         HDC hdc,                   // 绘制DC  
  113.         const CWFRect* dstRect,    // 绘制目标区域  
  114.         const CWFRect* srcRect     // 待绘制图片上的指定区域,NULL表示整个图片  
  115.         );  
  116.   
  117. //  
  118. public// 图像缩放旋转等相关接口  
  119.     // 缩放图像到IImage对象中,不改变自身数据  
  120.     typedef IImage* PWFIImage;  
  121.     BOOL ZoomToIImage(  
  122.         PWFIImage &pDstIImage,     // 存放缩放后图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放  
  123.         DWORD dwNewWidth,          // 缩放后图像宽度  
  124.         DWORD dwNewHeight          // 缩放后图像高度  
  125.         );  
  126.   
  127.     // 缩放图像(指定缩放后图像的宽度和高度)  
  128.     BOOL Zoom(  
  129.         DWORD dwNewWidth,          // 缩放后图像宽度  
  130.         DWORD dwNewHeight          // 缩放后图像高度  
  131.         );  
  132.       
  133.     // 缩放图像到目标对象中(指定缩放后图像的宽度和高度),不改变对象自身  
  134.     BOOL Zoom(  
  135.         CWFBitmap &dstBitmap,      // 带出缩放后的图像  
  136.         DWORD dwNewWidth,          // 缩放后图像宽度  
  137.         DWORD dwNewHeight          // 缩放后图像高度  
  138.         );  
  139.   
  140.     // 缩放图像(指定缩放X方向,Y方向缩放比率)  
  141.     BOOL ZoomEx(  
  142.         double dbZoomXRatio,       // X方向缩放率  
  143.         double dbZoomYRatio        // Y方向缩放率  
  144.         );  
  145.   
  146.     // 缩放图像到目标对象中(指定缩放X方向,Y方向缩放比率),不改变对象自身  
  147.     BOOL ZoomEx(  
  148.         CWFBitmap &dstBitmap,      // 带出缩放后的图像  
  149.         double dbZoomXRatio,       // X方向缩放率  
  150.         double dbZoomYRatio        // Y方向缩放率  
  151.         );  
  152.   
  153.     // 按特定角度旋转图像到IImage对象中,不改变自身数据  
  154.     // 顺时针旋转,只支持90, 180, 270, or 360  
  155.     BOOL RotateSpecificAngleToIImage(  
  156.         PWFIImage &pDstIImage,     // 存放旋转后图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放  
  157.         float fSpecificAngle       // 特定旋转角度(单位:度)  
  158.         );  
  159.   
  160.     // 按特定角度旋转图像  
  161.     // 顺时针旋转,只支持90, 180, 270, or 360  
  162.     BOOL RotateSpecificAngle(  
  163.         float fSpecificAngle       // 特定旋转角度(单位:度)  
  164.         );  
  165.   
  166.     // 按特定角度旋转图像到目标对象中,不改变对象自身  
  167.     // 顺时针旋转,只支持90, 180, 270, or 360  
  168.     BOOL RotateSpecificAngle(  
  169.         CWFBitmap &dstBitmap,      // 带出旋转后的图像  
  170.         float fSpecificAngle       // 特定旋转角度(单位:度)  
  171.         );  
  172.   
  173.     // 翻转图像到IImage对象中,不改变自身数据  
  174.     BOOL FlipToIImage(  
  175.         PWFIImage &pDstIImage,     // 存放翻转后图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放  
  176.         BOOL bFilpX,               // 是否反转X方向  
  177.         BOOL bFlipY                // 是否反转Y方向  
  178.         );  
  179.   
  180.     // 翻转图像  
  181.     BOOL Flip(  
  182.         BOOL bFilpX,               // 是否反转X方向  
  183.         BOOL bFlipY                // 是否反转Y方向  
  184.         );  
  185.   
  186.     // 翻转图像到目标对象中,不改变对象自身  
  187.     BOOL Flip(  
  188.         CWFBitmap &dstBitmap,      // 带出翻转后的图像  
  189.         BOOL bFilpX,               // 是否反转X方向  
  190.         BOOL bFlipY                // 是否反转Y方向  
  191.         );  
  192.   
  193.     // 裁剪图像上指定区域到IImage对象中,不改变自身数据  
  194.     BOOL CutToIImage(  
  195.         PWFIImage &pDstIImage,     // 存放裁剪图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放  
  196.         const RECT *pCutRect       // 在图像上裁剪的区域  
  197.         );  
  198.   
  199.     // 裁剪图像(图像改变为指定裁剪区域的图像)  
  200.     BOOL Cut(  
  201.         const RECT *pCutRect       // 在图像上裁剪的区域  
  202.         );  
  203.   
  204.     // 裁剪图像到目标对象中,不改变对象自身  
  205.     BOOL Cut(  
  206.         CWFBitmap &dstBitmap,      // 带出裁剪到的图像  
  207.         const RECT *pCutRect       // 在图像上裁剪的区域  
  208.         );  
  209.   
  210.     // 生成缩略图到指定IImage对象中,不改变自身数据  
  211.     BOOL ThumbnailToIImage(  
  212.         PWFIImage &pDstIImage,     // 存放缩略图的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放  
  213.         DWORD dwThumbWidth,        // 缩略图宽度  
  214.         DWORD dwThumbHeight        // 缩略图高度  
  215.         );   
  216.   
  217.     // 生成缩略图(指定像素宽度高度)(图像改变为缩略图)  
  218.     BOOL Thumbnail(  
  219.         DWORD dwThumbWidth,        // 缩略图宽度  
  220.         DWORD dwThumbHeight        // 缩略图高度  
  221.         );  
  222.   
  223.     // 生成缩略图(指定缩放比率)(图像改变为缩略图)  
  224.     BOOL ThumbnailEx(  
  225.         double dbXRatio,           // X方向缩放率  
  226.         double dbYRatio            // Y方向缩放率  
  227.         );  
  228.   
  229.     // 生成缩略图到目标对象中(指定像素宽度高度),不改变对象自身  
  230.     BOOL Thumbnail(  
  231.         CWFBitmap &dstBitmap,      // 带出旋转后的图像  
  232.         DWORD dwThumbWidth,        // 缩略图宽度  
  233.         DWORD dwThumbHeight        // 缩略图高度  
  234.         );  
  235.   
  236.     // 生成缩略图到目标对象中(指定缩放比率),不改变对象自身  
  237.     BOOL ThumbnailEx(  
  238.         CWFBitmap &dstBitmap,      // 带出旋转后的图像  
  239.         double dbXRatio,           // X方向缩放率  
  240.         double dbYRatio            // Y方向缩放率  
  241.         );  
  242.   
  243.     // 图像旋转任意角度到IBitmapImage对象中,不改变自身数据  
  244.     // 若只需要旋转90,180,270,360请调用接口RotateSpecificAngleToIImage   
  245.     typedef IBitmapImage* PWFIBitmapImage;  
  246.     BOOL RotateToIBitmapImage(  
  247.         PWFIBitmapImage &pDstIBitmapImage,     // 存放旋转后图像的IBitmapImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放  
  248.         float fAngle                           // 特定旋转角度(单位:度)  
  249.         );  
  250.   
  251.     // 按任意角度旋转图像      
  252.     // 若只需要旋转90,180,270,360请调用接口RotateSpecificAngle  
  253.     BOOL Rotate(  
  254.         float fAngle               // 特定旋转角度(单位:度)  
  255.         );  
  256.   
  257.     // 按任意角度旋转图像到目标对象中,不改变对象自身  
  258.     // 若只需要旋转90,180,270,360请调用接口RotateSpecificAngle  
  259.     BOOL Rotate(  
  260.         CWFBitmap &dstBitmap,      // 带出旋转后的图像  
  261.         float fAngle               // 特定旋转角度(单位:度)  
  262.         );  
  263.   
  264. //  
  265. public// 取得图像颜色数据相关接口  
  266.     // 获得图像数据(只含有各个点的颜色信息)  
  267.     BOOL GetColorBuf(  
  268.         unsigned char *pDataBuf,     // 存放图像数据缓冲区  
  269.         DWORD dwcbBufSize,           // 缓冲区实际大小(需要的大小通常是(宽度*高度*4))  
  270.         DWORD *pdwRealGetBytes=NULL  // 实际取得数据字节大小  
  271.         );  
  272.   
  273.     // 获得图片数据(只含有各个点的颜色信息)缓冲区地址,返回NULL表示没有图片数据  
  274.     const unsigned char* GetColorBufAddr(  
  275.         DWORD *pdwcbBufSize          // 带出颜色缓冲区字节大小  
  276.         );  
  277.   
  278. //  
  279. private// 私有成员变量    
  280.     IImage *m_pImage;             // 保存图像数据  
  281.     ImageInfo m_ImageInfo;        // 图像信息  
  282.     unsigned char *m_pImgDataBuf; // 保存原始图像数据(带有alpha通道数据)  
  283.     DWORD m_dwcbImgDataBufSize;   // 图像数据字节大小  
  284.     IBitmapImage *m_pBitmapImage; // 位图指针     
  285.   
  286.     // 先绘制到内存DC上,再次绘制直接由内存DC拷贝到目标DC  
  287.     HDC m_hDrawDC;         // 临时保存DC  
  288.     HBITMAP m_hBitmap;     // 临时保存图片  
  289.     HBITMAP m_hOldBitmap;   
  290.   
  291.     // 静态成员变量  
  292.     static DWORD m_dwObjCounts;                  // 对象数量  
  293.     static IImagingFactory *m_pImagingFactory;   // Image工厂接口对象  
  294.   
  295. private// 私有函数  
  296.     // 创建与释放Image工厂接口对象  
  297.     static BOOL CreateImagingFactory(void);  
  298.     static void DeleteImagingFactory(void);  
  299.   
  300.     // 为图片创建内存DC,及清除内存DC  
  301.     HDC CreateImgDC(HDC hdc);  
  302.     void DeleteImgDC(void);  
  303.   
  304.     // 取得图片原始数据,及销毁图片原始数据  
  305.     BOOL CreateImgDateBuf(void);  
  306.     void DeleteImgDateBuf(void);  
  307.   
  308.     // 拷贝一个IBitmapImage到另一个IBitmapImage中  
  309.     static BOOL CopyBitmapImage(  
  310.         IBitmapImage *pSrcBitmapImage,           // 源IBitmapImage  
  311.         PWFIBitmapImage &pDstBitmapImage         // 目标IBitmapImage  
  312.         );  
  313. };  
  314.   
  315. //  
  316. #endif  


源文件如下:

  1. /******************************************************************** 
  2.     Copyright(c) 2011,  
  3.     All rights reserved. 
  4.     purpose:    图片加载使用类 
  5.  
  6.     当前版本:   1.0 
  7.     作    者:   zhangwf 
  8.     创建日期:   2011:9:6 
  9.     完成日期:    
  10.      
  11.     取代版本: 
  12.     作    者: 
  13.     完成日期:    
  14. *********************************************************************/  
  15. #include "WFBitmap.h"  
  16. #include <initguid.h>  
  17. #include <imgguids.h>  
  18. //  
  19. // 声明及实现不需要给出接口的全局函数  
  20. // 路径是否有效  
  21. BOOL WFBING_PathEffective(LPCWSTR lpPathName);  
  22.   
  23. // 旋转图像数据缓冲区  
  24. typedef BYTE* PWFBYTE;  
  25. BOOL WFBING_RotateImageBuffer(  
  26.     const BYTE* pSrcBuf,                 // 待旋转原图像缓冲区(32位色,每个点有ARGB四个通道),缓冲区大小不能小于高度*宽度*4  
  27.     DWORD dwSrcWidth,                    // 原图像像素宽度  
  28.     DWORD dwSrcHeight,                   // 原图像像素高度  
  29.     double dbRotateAngle,                // 顺时针旋转角度(单位:度)  
  30.     PWFBYTE &pDstBuf,                    // 输出旋转后图像缓冲区(32位色,每个点有ARGB四个通道),带出的缓冲区大小为高度*宽度*4,需要外部释放  
  31.     DWORD &dwDstWidth,                   // 输出旋转后图像像素宽度   
  32.     DWORD &dwDstHeight,                  // 输出旋转后图像像素高度  
  33.     DWORD dwFillColor = 0x00FFFFFF       // 填充色(旋转后的图像比原图像大,空的部分使用该白色全透明颜色填充,ALPHA通道为0表示全透明)  
  34.     );  
  35.   
  36. //  
  37. // 路径是否有效  
  38. BOOL WFBING_PathEffective(LPCWSTR lpPathName)  
  39. {  
  40.     // 参数有效性  
  41.     if (lpPathName == NULL)  
  42.     {  
  43.         return FALSE;  
  44.     }  
  45.   
  46.     // 是否可以取得属性  
  47.     return (::GetFileAttributesW(lpPathName) == INVALID_FILE_ATTRIBUTES) ? FALSE : TRUE;  
  48. }  
  49.   
  50. // 旋转图像数据缓冲区  
  51. typedef BYTE* PWFBYTE;  
  52. BOOL WFBING_RotateImageBuffer(  
  53.     const BYTE* pSrcBuf,                 // 待旋转原图像缓冲区(32位色,每个点有ARGB四个通道)  
  54.     DWORD dwSrcWidth,                    // 原图像像素宽度  
  55.     DWORD dwSrcHeight,                   // 原图像像素高度  
  56.     double dbRotateAngle,                // 顺时针旋转角度(单位:度)  
  57.     PWFBYTE &pDstBuf,                    // 输出旋转后图像缓冲区(32位色,每个点有ARGB四个通道),带出的缓冲区大小为高度*宽度*4,需要外部释放  
  58.     DWORD &dwDstWidth,                   // 输出旋转后图像像素宽度   
  59.     DWORD &dwDstHeight,                  // 输出旋转后图像像素高度  
  60.     DWORD dwFillColor                    // 填充色(旋转后的图像比原图像大,空的部分使用该白色全透明颜色填充,ALPHA通道为0表示全透明)  
  61.     )  
  62. {  
  63.     // 参数有效性  
  64.     if (pSrcBuf==NULL || dwSrcWidth==0 || dwSrcHeight==0)  
  65.     {  
  66.         return FALSE;  
  67.     }  
  68.   
  69.     // 计算有效的旋转角,旋转一周视为没有旋转  
  70.     double dbAngle = (dbRotateAngle - (int)dbRotateAngle) + ((int)dbRotateAngle%360);  
  71.   
  72.     // 旋转角度过小不需要旋转,直接拷贝缓冲区  
  73.     if (dbAngle>=-0.0000001 && dbAngle<=0.0000001)  
  74.     {  
  75.         DWORD dwDstBufSize = dwSrcWidth*dwSrcHeight*4;  
  76.         pDstBuf = new BYTE[dwDstBufSize];  
  77.         if (pDstBuf == NULL)  
  78.         {  
  79.             printf("Rotate Angle Zero New Buf Error!\n");  
  80.             return FALSE;  
  81.         }  
  82.   
  83.         // 拷贝数据  
  84.         memset(pDstBuf, 0, dwDstBufSize);  
  85.         memcpy(pDstBuf, pSrcBuf, dwDstBufSize);  
  86.         dwDstWidth = dwSrcWidth;  
  87.         dwDstHeight = dwSrcHeight;  
  88.         return TRUE;  
  89.     }  
  90.   
  91.     // 计算sin(dbAngle)和cos(dbAngle)的值  
  92.     double dbPI = 3.1415926535;  
  93.     double dbA = dbAngle*dbPI/180;  
  94.     double dbSinA = sin(dbA);  
  95.     double dbCosA = cos(dbA);  
  96.   
  97.     // 计算除去左上顶点外的其他三个顶点旋转后坐标  
  98.     // 旋转坐标公式:X'= X*cosθ -  Y*sinθ;Y' =  X*sinθ + Y*cosθ;其中θ为顺时针旋转角度  
  99.     // 以图像左上角为原点,向右为X正方向,向下为Y正方向;  
  100.     // 其他顶点坐标为(dwSrcWidth, 0),(dwSrcWidth, dwSrcHeight),(0, dwSrcHeight)  
  101.     double dbX1 = (double)dwSrcWidth*dbCosA - 0*dbSinA;  
  102.     double dbY1 = (double)dwSrcWidth*dbSinA + 0*dbCosA;  
  103.     double dbX2 = (double)dwSrcWidth*dbCosA - (double)dwSrcHeight*dbSinA;  
  104.     double dbY2 = (double)dwSrcWidth*dbSinA + (double)dwSrcHeight*dbCosA;  
  105.     double dbX3 = 0*dbCosA - (double)dwSrcHeight*dbSinA;  
  106.     double dbY3 = 0*dbSinA + (double)dwSrcHeight*dbCosA;  
  107.   
  108.     // 计算旋转后4个顶点XY方向最大最小坐标值,用于确定旋转后图像大小  
  109.     double dbMaxX = max(dbX3, max(dbX2, max(0, dbX1)));   
  110.     double dbMinX = min(dbX3, min(dbX2, min(0, dbX1)));   
  111.     double dbMaxY = max(dbY3, max(dbY2, max(0, dbY1)));   
  112.     double dbMinY = min(dbY3, min(dbY2, min(0, dbY1)));   
  113.   
  114.     // 计算旋转后图像的宽度和高度  
  115.     DWORD dwUseWidth = (DWORD)fabs(dbMaxX - dbMinX) + 1;  
  116.     DWORD dwUseHeight = (DWORD)fabs(dbMaxY - dbMinY) + 1;  
  117.   
  118.     // 为旋转后图像申请数据缓冲区  
  119.     pDstBuf = new BYTE[dwUseWidth*dwUseHeight*4];  
  120.     if (pDstBuf == NULL)  
  121.     {  
  122.         printf("Rotate Angle New Buf[%d] Error!\n", dwUseWidth*dwUseHeight*4);  
  123.         return FALSE;  
  124.     }  
  125.   
  126.     // 带出旋转后图像大小  
  127.     dwDstWidth = dwUseWidth;  
  128.     dwDstHeight = dwUseHeight;  
  129.   
  130.     // 旋转后的图像会出现超出坐标系区域,需要坐标平移  
  131.     // 旋转平移变换坐标公式:X'= X*cosθ -  Y*sinθ - dbMinX;Y' =  X*sinθ + Y*cosθ - dbMinY;其中θ为顺时针旋转角度  
  132.     // 填充旋转后图像数据时就需要直到每个点对应原图像位置,所以公式变换为:  
  133.     // X = (X'+dbMinX)*cosθ + (Y'+dbMinY)*sinθ;  
  134.     // Y = (Y'+dbMinY)*conθ - (X'+dbMinX)*sinθ;  
  135.     // 计算出的原图像上(X,Y)坐标不是整数,到底选取哪一点的颜色值来填充旋转后的区域呢?  
  136.     // 若(X,Y)不在原图像区域上,则用默认颜色填充;  
  137.     // 若在元图像上,从图像质量及效率的考虑上,通常选择双线性插值获取旋转后该位置的颜色  
  138.     // 双线性插值取的是与(X,Y)临近的4个点的颜色值来计算旋转后该位置的颜色值  
  139.     /************************************************************************************ 
  140.     双线性内插值: 
  141.         对于一个目的像素,设置坐标通过反向变换得到的浮点坐标为(i+u,j+v), 
  142.         其中i、j均为非负整数,u、v为[0,1)区间的浮点数,则这个像素得值f(i+u,j+v)可由原图像 
  143.         中坐标为 (i,j)、(i+1,j)、(i,j+1)、(i+1,j+1)所对应的周围四个像素的值决定, 
  144.         即: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) 
  145.         其中f(i,j)表示源图像(i,j)处的的像素值,以此类推。 
  146.     ************************************************************************************/  
  147.     // 遍历目标图像上每一个点,依次填充颜色  
  148.     double dbSrcX = 0;           // 对应原图像上X坐标位置(不为整数)  
  149.     double dbSrcY = 0;           // 对应原图像上Y坐标位置(不为整数)  
  150.     DWORD dwSrcI = 0;            // 对应dbSrcX的整数部分  
  151.     DWORD dwSrcJ = 0;            // 对应dbSrcY的整数部分  
  152.     double dbSrcU = 0;           // 对应dbSrcX-dwSrcI  
  153.     double dbSrcV = 0;           // 对应dbSrcY-dwSrcJ  
  154.   
  155.     DWORD *pdwDstBuf = (DWORD*)pDstBuf;  // 以4字节方式使用目标缓冲区  
  156.     DWORD *pdwSrcBuf = (DWORD*)pSrcBuf;  // 以4字节方式使用原图像缓冲区  
  157.     BYTE *pByteTmpBuf = NULL;            // 临时使用指针  
  158.   
  159.     DWORD *pSrcIJ = NULL;        // (I,J)位置颜色  
  160.     DWORD *pSrcI1J = NULL;       // (I+1,J)位置颜色  
  161.     DWORD *pSrcIJ1 = NULL;       // (I,J+1)位置颜色  
  162.     DWORD *pSrcI1J1 = NULL;      // (I+1,J+1)位置颜色  
  163.       
  164.     DWORD dwY = 0;  
  165.     DWORD dwX = 0;  
  166.     DWORD dwColorBit = 0;  
  167.     for (dwY=0; dwY<dwUseHeight; dwY++)  
  168.     {  
  169.         for (dwX=0; dwX<dwUseWidth; dwX++)  
  170.         {  
  171.             // 坐标变换公式  
  172.             // X = (X'+dbMinX)*cosθ + (Y'+dbMinY)*sinθ;  
  173.             // Y = (Y'+dbMinY)*conθ - (X'+dbMinX)*sinθ;  
  174.             dbSrcX = ((double)dwX + dbMinX)*dbCosA + ((double)dwY + dbMinY)*dbSinA;  
  175.             dbSrcY = ((double)dwY + dbMinY)*dbCosA - ((double)dwX + dbMinX)*dbSinA;  
  176.   
  177.             // 坐标点不在原图像区域,使用默认颜色填充  
  178.             if (dbSrcX<0 || dbSrcX>=(double)dwSrcWidth || dbSrcY<0 || dbSrcY>=(double)dwSrcHeight)  
  179.             {  
  180.                 pdwDstBuf[dwY*dwUseWidth + dwX] = dwFillColor;  
  181.             }  
  182.             // 在原图像范围内,则使用双线性插值计算当前颜色  
  183.             else  
  184.             {  
  185.                 // 计算位置  
  186.                 dwSrcI = (DWORD)dbSrcX;  
  187.                 dwSrcJ = (DWORD)dbSrcY;  
  188.                 dbSrcU = dbSrcX - dwSrcI;  
  189.                 dbSrcV = dbSrcY - dwSrcJ;  
  190.   
  191.                 // 得到临近4个位置颜色位置指针  
  192.                 pSrcIJ = pdwSrcBuf + (dwSrcJ*dwSrcWidth + dwSrcI);  
  193.                 pSrcI1J = (dwSrcI+1 < dwSrcWidth) ? (pSrcIJ + 1) : pSrcIJ;  
  194.                 pSrcI1J1 = (dwSrcI+1<dwSrcWidth && dwSrcJ+1<dwSrcHeight) ? (pdwSrcBuf + ((dwSrcJ+1)*dwSrcWidth + dwSrcI + 1)) : pSrcIJ;  
  195.                 pSrcIJ1 = (dwSrcJ+1 < dwSrcHeight) ? (pdwSrcBuf + ((dwSrcJ+1)*dwSrcWidth + dwSrcI)) : pSrcIJ;  
  196.   
  197.                 // 根据插值公式计算颜色值  
  198.                 // 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)  
  199.                 pByteTmpBuf = (BYTE*)(pdwDstBuf + (dwY*dwUseWidth + dwX));  
  200.                 for (dwColorBit=0; dwColorBit<4; dwColorBit++)  
  201.                 {  
  202.                     pByteTmpBuf[dwColorBit] =   (BYTE)(  (1-dbSrcU)*(1-dbSrcV)*((BYTE*)pSrcIJ)[dwColorBit]   
  203.                                                        + (1-dbSrcU)*dbSrcV*((BYTE*)pSrcIJ1)[dwColorBit]  
  204.                                                        + dbSrcU*(1-dbSrcV)*((BYTE*)pSrcI1J)[dwColorBit]  
  205.                                                        + dbSrcU*dbSrcV*((BYTE*)pSrcI1J1)[dwColorBit]  
  206.                                                        );  
  207.                 }  
  208.             }  
  209.         }  
  210.     }  
  211.   
  212.     // 旋转成功  
  213.     return TRUE;  
  214. }  
  215.   
  216. //  
  217. // 初始化静态成员变量  
  218. DWORD CWFBitmap::m_dwObjCounts = 0;  
  219. IImagingFactory* CWFBitmap::m_pImagingFactory = NULL;  
  220. //  
  221. // 构造函数  
  222. CWFBitmap::CWFBitmap()  
  223. : m_pImgDataBuf(NULL)  
  224. , m_dwcbImgDataBufSize(0)  
  225. {  
  226.     // 创建Image工厂接口对象  
  227.     CreateImagingFactory();  
  228.   
  229.     // 初始化变量  
  230.     m_pImage = NULL;  
  231.     memset(&m_ImageInfo, 0, sizeof(m_ImageInfo));  
  232.     m_hDrawDC = NULL;  
  233.     m_hBitmap = NULL;  
  234.     m_hOldBitmap = NULL;      
  235.     m_pBitmapImage = NULL;    
  236. }  
  237.   
  238. // 析构函数  
  239. CWFBitmap::~CWFBitmap()  
  240. {  
  241.     // 释放占用资源  
  242.     Release();  
  243.   
  244.     // 释放Image工厂接口对象  
  245.     DeleteImagingFactory();  
  246. }  
  247.   
  248.   
  249. // 拷贝构造函数  
  250. CWFBitmap::CWFBitmap(const CWFBitmap &other)  
  251. : m_pImgDataBuf(NULL)  
  252. , m_dwcbImgDataBufSize(0)  
  253. {  
  254.     // 创建Image工厂接口对象  
  255.     CreateImagingFactory();  
  256.   
  257.     // 初始化变量  
  258.     m_pImage = NULL;  
  259.     memset(&m_ImageInfo, 0, sizeof(m_ImageInfo));  
  260.     m_hDrawDC = NULL;  
  261.     m_hBitmap = NULL;  
  262.     m_hOldBitmap = NULL;      
  263.     m_pBitmapImage = NULL;    
  264.   
  265.     // 拷贝图片信息  
  266.     m_ImageInfo = other.m_ImageInfo;  
  267.   
  268.     // 拷贝IImage  
  269.     if (other.m_pImage != NULL)  
  270.     {     
  271.         other.m_pImage->QueryInterface(IID_IImage, (void **)&m_pImage);    
  272.     }  
  273.   
  274.     // 拷贝图片数据  
  275.     if (other.m_pImgDataBuf!=NULL && other.m_dwcbImgDataBufSize!=0)  
  276.     {  
  277.         m_pImgDataBuf = new unsigned char[other.m_dwcbImgDataBufSize];  
  278.         if (m_pImgDataBuf != NULL)  
  279.         {  
  280.             m_dwcbImgDataBufSize = other.m_dwcbImgDataBufSize;  
  281.             memcpy(m_pImgDataBuf, other.m_pImgDataBuf, m_dwcbImgDataBufSize);  
  282.         }  
  283.     }  
  284. }  
  285.   
  286. // 赋值函数  
  287. CWFBitmap& CWFBitmap::operator=(const CWFBitmap &other)  
  288. {  
  289.     // 检查自赋值  
  290.     if (this == &other)  
  291.     {  
  292.         return *this;  
  293.     }  
  294.   
  295.     // 释放资源  
  296.     Release();  
  297.   
  298.     // 拷贝图片信息  
  299.     m_ImageInfo = other.m_ImageInfo;  
  300.   
  301.     // 拷贝IImage  
  302.     if (other.m_pImage != NULL)  
  303.     {     
  304.         other.m_pImage->QueryInterface(IID_IImage, (void **)&m_pImage);    
  305.     }  
  306.   
  307.     // 拷贝图片数据  
  308.     if (other.m_pImgDataBuf!=NULL && other.m_dwcbImgDataBufSize!=0)  
  309.     {  
  310.         m_pImgDataBuf = new unsigned char[other.m_dwcbImgDataBufSize];  
  311.         if (m_pImgDataBuf != NULL)  
  312.         {  
  313.             m_dwcbImgDataBufSize = other.m_dwcbImgDataBufSize;  
  314.             memcpy(m_pImgDataBuf, other.m_pImgDataBuf, m_dwcbImgDataBufSize);  
  315.         }  
  316.     }   
  317.   
  318.     // 返回当前对象  
  319.     return *this;  
  320. }  
  321.   
  322. // 从文件中加载  
  323. BOOL CWFBitmap::LoadFromFile(  
  324.     LPCWSTR lpFileName         // 文件绝对路径  
  325.     )  
  326. {  
  327.     // 释放上次图片数据  
  328.     Release();  
  329.   
  330.     // 路径有效性  
  331.     if (WFBING_PathEffective(lpFileName) == FALSE)  
  332.     {  
  333.         return FALSE;  
  334.     }  
  335.   
  336.     // 创建Image工厂接口对象失败  
  337.     if (m_pImagingFactory == NULL)  
  338.     {  
  339.         return FALSE;  
  340.     }  
  341.   
  342.     // 从文件中创建图片  
  343.     HRESULT hr = NULL;  
  344.     if(FAILED(hr = m_pImagingFactory->CreateImageFromFile(lpFileName, &m_pImage)))  
  345.     {  
  346.         return FALSE;  
  347.     }  
  348.   
  349.     // 得到图片信息  
  350.     if(FAILED(hr = m_pImage->GetImageInfo(&m_ImageInfo)))  
  351.     {  
  352.         return FALSE;  
  353.     }  
  354.   
  355.     // 成功获得图片信息  
  356.     return TRUE;  
  357. }  
  358.   
  359. // 从资源中加载,例如LoadFromResource(MAKEINTRESOURCE(IDR_BACKIMG), _T("PNG"));  
  360. BOOL CWFBitmap::LoadFromResource(  
  361.     LPCWSTR lpName,            // 资源名称比如:MAKEINTRESOURCE(IDR_BACKIMG)              
  362.     LPCWSTR lpType             // 资源类型比如:_T("PNG")  
  363.     )  
  364. {  
  365.     // 释放上次图片数据  
  366.     Release();  
  367.   
  368.     // 创建Image工厂接口对象失败  
  369.     if (m_pImagingFactory == NULL)  
  370.     {  
  371.         return FALSE;  
  372.     }     
  373.   
  374.     // 在资源中寻找  
  375.     HMODULE hModule_Current = ::GetModuleHandle(NULL);  
  376.     HRSRC hr = ::FindResource(hModule_Current, lpName, lpType);  
  377.     DWORD dwsize = ::SizeofResource(GetModuleHandle(NULL), hr);  
  378.     HGLOBAL hg = ::LoadResource(GetModuleHandle(NULL), hr);  
  379.     LPSTR lp = (LPSTR)::LockResource(hg);  
  380.       
  381.     // 从缓冲区创建图片  
  382.     HRESULT hrt = NULL;  
  383.     if(FAILED(hrt = m_pImagingFactory->CreateImageFromBuffer(lp, dwsize, DISPOSAL_NONE, &m_pImage)))  
  384.     {  
  385.         ::DeleteObject(hr);  
  386.         return FALSE;  
  387.     }  
  388.   
  389.     // 得到图片信息  
  390.     if(FAILED(hrt = m_pImage->GetImageInfo(&m_ImageInfo)))  
  391.     {  
  392.         ::DeleteObject(hr);  
  393.         return FALSE;  
  394.     }  
  395.   
  396.     // 成功获得图片信息  
  397.     ::DeleteObject(hr);  
  398.     return TRUE;  
  399. }  
  400.   
  401. // 从缓冲区中加载  
  402. BOOL CWFBitmap::LoadFromBuffer(  
  403.     const unsigned char *pBuf,      // 缓冲区地址  
  404.     DWORD dwcbBufSize               // 缓冲区字节大小  
  405.     )  
  406. {  
  407.     // 释放上次图片数据  
  408.     Release();  
  409.   
  410.     // 参数有效性  
  411.     if (pBuf==NULL || dwcbBufSize==0)  
  412.     {  
  413.         return FALSE;  
  414.     }  
  415.   
  416.     // 创建Image工厂接口对象失败  
  417.     if (m_pImagingFactory == NULL)  
  418.     {  
  419.         return FALSE;  
  420.     }  
  421.   
  422.     // 从文件中创建图片  
  423.     HRESULT hr = NULL;  
  424.     if(FAILED(hr = m_pImagingFactory->CreateImageFromBuffer(pBuf, dwcbBufSize, DISPOSAL_NONE, &m_pImage)))  
  425.     {  
  426.         return FALSE;  
  427.     }  
  428.   
  429.     // 得到图片信息  
  430.     if(FAILED(hr = m_pImage->GetImageInfo(&m_ImageInfo)))  
  431.     {  
  432.         return FALSE;  
  433.     }  
  434.   
  435.     // 成功获得图片信息  
  436.     return TRUE;  
  437. }  
  438.   
  439. // 从IImage对象中加载  
  440. BOOL CWFBitmap::LoadFromIImage(  
  441.     IImage *pIImage            // IImage对象  
  442.     )  
  443. {  
  444.     // 释放上次图片数据  
  445.     Release();  
  446.   
  447.     // 参数有效性  
  448.     if (pIImage == NULL)  
  449.     {  
  450.         return FALSE;  
  451.     }  
  452.   
  453.     // 得到IImage对象  
  454.     HRESULT hr = pIImage->QueryInterface(IID_IImage, (void **)&m_pImage);      
  455.     if (FAILED(hr))  
  456.     {  
  457.         return FALSE;  
  458.     }  
  459.   
  460.     // 得到图片信息  
  461.     if(FAILED(hr = m_pImage->GetImageInfo(&m_ImageInfo)))  
  462.     {  
  463.         return FALSE;  
  464.     }  
  465.   
  466.     // 加载成功  
  467.     return TRUE;  
  468. }  
  469.   
  470. // 从IBitmapImage对象中加载  
  471. BOOL CWFBitmap::LoadFromIBitmapImage(  
  472.     IBitmapImage *pBitmapImage // IBitmapImage对象   
  473.     )  
  474. {  
  475.     // 释放上次数据  
  476.     Release();  
  477.   
  478.     // 参数有效性  
  479.     if (pBitmapImage == NULL)  
  480.     {  
  481.         return FALSE;  
  482.     }  
  483.   
  484.     // 拷贝到新的IBitmapImage对象   
  485.     if (CopyBitmapImage(pBitmapImage, m_pBitmapImage) == FALSE)  
  486.     {  
  487.         return FALSE;  
  488.     }  
  489.   
  490.     // 得到新的IImage  
  491.     m_pBitmapImage->QueryInterface(IID_IImage, (void**)&m_pImage);  
  492.   
  493.     // 得到新的ImageInfo      
  494.     if (m_pImage != NULL)  
  495.     {  
  496.         m_pImage->GetImageInfo(&m_ImageInfo);  
  497.     }     
  498.   
  499.     // 成功  
  500.     return TRUE;  
  501. }  
  502.   
  503. // 释放占用的资源  
  504. void CWFBitmap::Release(void)  
  505. {  
  506.     // 释放DC  
  507.     DeleteImgDC();  
  508.   
  509.     // 释放原始数据空间  
  510.     DeleteImgDateBuf();  
  511.   
  512.     // 释放IMAGE  
  513.     if(m_pImage != NULL)  
  514.     {  
  515.         m_pImage->Release();  
  516.         m_pImage = NULL;  
  517.     }  
  518.   
  519.     // 释放IBitmapImage  
  520.     if (m_pBitmapImage != NULL)  
  521.     {  
  522.         m_pBitmapImage->Release();  
  523.         m_pBitmapImage = NULL;  
  524.     }  
  525. }  
  526.   
  527. // 绘制整个图像到指定位置(会把图像压缩或拉伸填充到指定区域)  
  528. void CWFBitmap::Draw(  
  529.     HDC hdc,                   // 绘制DC   
  530.     const RECT* dstRect        // 绘制目标区域  
  531.     )  
  532. {  
  533.     // 获取图像信息失败  
  534.     if (m_pImage==NULL || dstRect==NULL)  
  535.     {  
  536.         return;  
  537.     }  
  538.   
  539.     // 绘制图像  
  540.     m_pImage->Draw(hdc, dstRect, NULL);        
  541. }  
  542.   
  543. // 绘制图像上一部分到指定的部分(先绘制到内存DC,再绘制到目标DC)  
  544. void CWFBitmap::Draw(  
  545.     HDC hdc,                   // 绘制DC  
  546.     const RECT* dstRect,       // 绘制目标区域  
  547.     const RECT* srcRect        // 待绘制图片上的指定区域,NULL表示整个图片  
  548.     )  
  549. {  
  550.     // 获取图像信息失败,目标绘图区为NULL  
  551.     if (m_pImage==NULL || dstRect==NULL)  
  552.     {  
  553.         return;  
  554.     }     
  555.   
  556.     // 创建内存DC  
  557.     if (m_hDrawDC == NULL)  
  558.     {  
  559.         m_hDrawDC = CreateImgDC(hdc);  
  560.     }  
  561.   
  562.     // 把内存DC上指定的部分拷贝到目标DC上  
  563.     if (srcRect != NULL)  
  564.     {  
  565.         ::StretchBlt(hdc,   
  566.             dstRect->left,   
  567.             dstRect->top,   
  568.             dstRect->right-dstRect->left,   
  569.             dstRect->bottom-dstRect->top,   
  570.             m_hDrawDC,   
  571.             srcRect->left,   
  572.             srcRect->top,   
  573.             srcRect->right-srcRect->left,   
  574.             srcRect->bottom-srcRect->top,   
  575.             SRCCOPY  
  576.             );    
  577.     }  
  578.     else  
  579.     {  
  580.         ::BitBlt(hdc,   
  581.             dstRect->left,   
  582.             dstRect->top,   
  583.             dstRect->right-dstRect->left,   
  584.             dstRect->bottom-dstRect->top,   
  585.             m_hDrawDC,   
  586.             0,   
  587.             0,  
  588.             SRCCOPY  
  589.             );  
  590.     }     
  591. }  
  592.   
  593. // 绘制图像上一部分到指定的区域(支持alpha混合)  
  594. void CWFBitmap::DrawAlpha(  
  595.     HDC hdc,                   // 绘制DC  
  596.     const RECT* dstRect,       // 绘制目标区域  
  597.     const RECT* srcRect        // 待绘制图片上的指定区域,NULL表示整个图片  
  598.     )  
  599. {  
  600.     // 获取图像信息失败,目标绘图区为NULL  
  601.     if (m_pImage==NULL || dstRect==NULL)  
  602.     {  
  603.         return;  
  604.     }  
  605.   
  606.     // 获取原始数据失败  
  607.     if (CreateImgDateBuf() == FALSE)  
  608.     {  
  609.         return;  
  610.     }     
  611.   
  612.     // 计算目标区域宽度及高度  
  613.     int nDstWidth = dstRect->right - dstRect->left;  
  614.     int nDstHeight = dstRect->bottom - dstRect->top;  
  615.   
  616.     // 创建目标绘制区域大小的内存DC  
  617.     HDC hDIBDC = CreateCompatibleDC(hdc);  
  618.     BITMAPINFO hdr;   
  619.     ZeroMemory(&hdr , sizeof(BITMAPINFO));  
  620.     hdr.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);  
  621.     hdr.bmiHeader.biWidth = nDstWidth;  
  622.     hdr.bmiHeader.biHeight = -nDstHeight;  
  623.     hdr.bmiHeader.biPlanes = 1;  
  624.     hdr.bmiHeader.biBitCount = 32;  
  625.     BYTE * pbtPixels = NULL;   
  626.     HBITMAP hDIBitmap = CreateDIBSection(hDIBDC, (BITMAPINFO *)&hdr, DIB_RGB_COLORS, (void **)&pbtPixels, NULL, 0);  
  627.     HBITMAP hOldBmp = (HBITMAP)SelectObject(hDIBDC, hDIBitmap);  
  628.   
  629.     // 拷贝背景DC上目标绘制区域到内存DC  
  630.     ::StretchBlt(hDIBDC, 0, 0, nDstWidth, nDstHeight, hdc, dstRect->left, dstRect->top, nDstWidth, nDstHeight, SRCCOPY);    
  631.   
  632.     // 计算使用图片上的源区域大小  
  633.     RECT rcImgSrc;  
  634.     if (srcRect != NULL)  
  635.     {  
  636.         rcImgSrc = *srcRect;  
  637.     }  
  638.     else  
  639.     {  
  640.         rcImgSrc.left = 0;  
  641.         rcImgSrc.top = 0;  
  642.         rcImgSrc.right = m_ImageInfo.Width;  
  643.         rcImgSrc.bottom = m_ImageInfo.Height;  
  644.     }  
  645.   
  646.     // 计算实际使用区域的宽度和高度  
  647.     int nUseWidth = (nDstWidth < rcImgSrc.right-rcImgSrc.left) ? nDstWidth : rcImgSrc.right-rcImgSrc.left;  
  648.     int nUseHeight = (nDstHeight < rcImgSrc.bottom-rcImgSrc.top) ? nDstHeight : rcImgSrc.bottom-rcImgSrc.top;  
  649.   
  650.     // 进行Alpha混合运算    
  651.     BYTE btAlphaSRC = 0;  
  652.     int iSrcPos = 0;  
  653.     int iDstPos = 0;  
  654.     for(int i=0; i<nUseHeight; i++)  
  655.     {         
  656.         for(int j=0;  j<nUseWidth; j++)  
  657.         {         
  658.             // 计算源及目标索引及该点ALPHA值  
  659.             iSrcPos = (i*m_ImageInfo.Width + rcImgSrc.left + j) * 4;  
  660.             iDstPos = (i*nDstWidth + j) * 4;          
  661.             btAlphaSRC = m_pImgDataBuf[iSrcPos+3];  
  662.   
  663.             // 计算目标像素值,ALPHA混合result = ALPHA * srcPixel + ( 1 - ALPHA ) * destPixel           
  664.             pbtPixels[iDstPos] = ((255-btAlphaSRC)*pbtPixels[iDstPos] + btAlphaSRC*m_pImgDataBuf[iSrcPos])/255;  
  665.             pbtPixels[iDstPos+1] = ((255-btAlphaSRC)*pbtPixels[iDstPos+1] + btAlphaSRC*m_pImgDataBuf[iSrcPos+1])/255;  
  666.             pbtPixels[iDstPos+2] = ((255-btAlphaSRC)*pbtPixels[iDstPos+2] + btAlphaSRC*m_pImgDataBuf[iSrcPos+2])/255;         
  667.         }             
  668.     }  
  669.   
  670.     // 混合ALPHA后的内存DC拷贝到目标DC  
  671.     BitBlt(hdc, dstRect->left, dstRect->top, nDstWidth, nDstHeight, hDIBDC, 0, 0, SRCCOPY);  
  672.   
  673.     // 释放临时内存DC  
  674.     SelectObject(hDIBDC, hOldBmp);    
  675.     DeleteObject(hDIBDC);  
  676.     DeleteObject(hDIBitmap);  
  677. }  
  678.   
  679. // 绘制整个图像到自定义矩形类型区域(会把图像压缩或拉伸填充到指定区域)  
  680. void CWFBitmap::DrawEx(  
  681.     HDC hdc,                   // 绘制DC   
  682.     const CWFRect* dstRect     // 绘制目标区域  
  683.     )  
  684. {  
  685.     // 参数有效性  
  686.     if (dstRect == NULL)  
  687.     {  
  688.         return;  
  689.     }  
  690.   
  691.     // 转换矩形区域  
  692.     RECT rcDst = {dstRect->x, dstRect->y, dstRect->x+dstRect->w, dstRect->y+dstRect->h};  
  693.     Draw(hdc, &rcDst);  
  694. }  
  695.   
  696. // 绘制图像上一部分到指定的自定义矩形类型区域(先绘制到内存DC,再绘制到目标DC)  
  697. void CWFBitmap::DrawEx(  
  698.     HDC hdc,                   // 绘制DC  
  699.     const CWFRect* dstRect,    // 绘制目标区域  
  700.     const CWFRect* srcRect     // 待绘制图片上的指定区域,NULL表示整个图片  
  701.     )  
  702. {  
  703.     // 参数有效性  
  704.     if (dstRect == NULL)  
  705.     {  
  706.         return;  
  707.     }  
  708.   
  709.     // 转换得到目标矩形区域  
  710.     RECT rcDst = {dstRect->x, dstRect->y, dstRect->x+dstRect->w, dstRect->y+dstRect->h};  
  711.   
  712.     // 转换得到源矩形区域  
  713.     RECT rcSrc = {0};  
  714.     if (srcRect != NULL)  
  715.     {  
  716.         rcSrc.left = srcRect->x;  
  717.         rcSrc.top = srcRect->y;  
  718.         rcSrc.right = srcRect->x + srcRect->w;  
  719.         rcSrc.bottom = srcRect->y + srcRect->h;  
  720.     }  
  721.     Draw(hdc, &rcDst, (srcRect==NULL) ? NULL : &rcSrc);  
  722. }  
  723.   
  724. // 绘制图像上一部分到指定的自定义矩形类型区域(支持alpha混合)  
  725. void CWFBitmap::DrawAlphaEx(  
  726.     HDC hdc,                   // 绘制DC  
  727.     const CWFRect* dstRect,    // 绘制目标区域  
  728.     const CWFRect* srcRect     // 待绘制图片上的指定区域,NULL表示整个图片  
  729.     )  
  730. {  
  731.     // 参数有效性  
  732.     if (dstRect == NULL)  
  733.     {  
  734.         return;  
  735.     }  
  736.   
  737.     // 转换得到目标矩形区域  
  738.     RECT rcDst = {dstRect->x, dstRect->y, dstRect->x+dstRect->w, dstRect->y+dstRect->h};  
  739.   
  740.     // 转换得到源矩形区域  
  741.     RECT rcSrc = {0};  
  742.     if (srcRect != NULL)  
  743.     {  
  744.         rcSrc.left = srcRect->x;  
  745.         rcSrc.top = srcRect->y;  
  746.         rcSrc.right = srcRect->x + srcRect->w;  
  747.         rcSrc.bottom = srcRect->y + srcRect->h;  
  748.     }  
  749.     DrawAlpha(hdc, &rcDst, (srcRect==NULL) ? NULL : &rcSrc);  
  750. }  
  751.   
  752. // 获得图像的宽度,未加载到图片返回0  
  753. DWORD CWFBitmap::Width() const  
  754. {  
  755.     return m_ImageInfo.Width;  
  756. }  
  757.   
  758. // 获得图像的高度,未加载到图片返回0  
  759. DWORD CWFBitmap::Height() const  
  760. {  
  761.     return m_ImageInfo.Height;  
  762. }  
  763.   
  764. BOOL CWFBitmap::ZoomToIImage(  
  765.     PWFIImage &pDstIImage,     // 存放缩放后图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放  
  766.     DWORD dwNewWidth,          // 缩放后图像宽度  
  767.     DWORD dwNewHeight          // 缩放后图像高度  
  768.     )  
  769. {  
  770.     // 释放目标IImage对象  
  771.     if (pDstIImage != NULL)  
  772.     {  
  773.         pDstIImage->Release();  
  774.         pDstIImage = NULL;  
  775.     }  
  776.       
  777.     // 参数有效性  
  778.     if (dwNewWidth==0 || dwNewHeight==0 || m_pImage==NULL || m_pImagingFactory==NULL)  
  779.     {  
  780.         return FALSE;  
  781.     }  
  782.   
  783.     // 使用到的临时变量,由于后面使用了goto在此处定义  
  784.     BOOL bRet = TRUE;                       // 函数返回值  
  785.     IBitmapImage *pBmp = NULL;              // 位图接口  
  786.     IBitmapImage *pNewBmp = NULL;           // 缩放后位图接口  
  787.     IBasicBitmapOps *pBmpOps = NULL;        // 位图操作接口  
  788.   
  789.     // 得到位图接口     
  790.     HRESULT hr = m_pImagingFactory->CreateBitmapFromImage(m_pImage, m_ImageInfo.Width, m_ImageInfo.Height, m_ImageInfo.PixelFormat, InterpolationHintDefault, &pBmp);  
  791.     if (FAILED(hr))  
  792.     {  
  793.         printf("ZoomToIImage CreateBitmapFromImage Error!\n");  
  794.         bRet = FALSE;  
  795.         goto ERROR_END_FUNCTIONFLAG;  
  796.     }  
  797.   
  798.     // 得到位图操作接口   
  799.     hr = pBmp->QueryInterface(IID_IBasicBitmapOps,(void **)&pBmpOps);  
  800.     if (FAILED(hr))  
  801.     {  
  802.         printf("ZoomToIImage QueryInterface IID_IBasicBitmapOps Error!\n");  
  803.         bRet = FALSE;  
  804.         goto ERROR_END_FUNCTIONFLAG;          
  805.     }  
  806.   
  807.     // 缩放位图  
  808.     hr = pBmpOps->Resize(dwNewWidth, dwNewHeight, m_ImageInfo.PixelFormat, InterpolationHintDefault, &pNewBmp);  
  809.     if (FAILED(hr))  
  810.     {  
  811.         printf("ZoomToIImage Resize Error!\n");  
  812.         bRet = FALSE;  
  813.         goto ERROR_END_FUNCTIONFLAG;  
  814.     }  
  815.   
  816.     // 得到新IImage  
  817.     hr = pNewBmp->QueryInterface(IID_IImage,(void **)&pDstIImage);  
  818.     if (FAILED(hr))  
  819.     {  
  820.         printf("ZoomToIImage QueryInterface pDstIImage Error!\n");  
  821.         bRet = FALSE;  
  822.         goto ERROR_END_FUNCTIONFLAG;  
  823.     }  
  824.   
  825.     // 正确得到缩放后的IImage  
  826.     bRet = TRUE;  
  827.   
  828.     // 进入释放过程  
  829. ERROR_END_FUNCTIONFLAG:  
  830.     // 释放位图  
  831.     if (pBmp != NULL)  
  832.     {  
  833.         pBmp->Release();  
  834.         pBmp = NULL;  
  835.     }  
  836.   
  837.     // 释放缩放后位图  
  838.     if (pNewBmp != NULL)  
  839.     {  
  840.         pNewBmp->Release();  
  841.         pNewBmp = NULL;  
  842.     }  
  843.   
  844.     // 释放位图操作接口  
  845.     if (pBmpOps != NULL)  
  846.     {  
  847.         pBmpOps->Release();  
  848.         pBmpOps = NULL;  
  849.     }  
  850.   
  851.     // 返回结果  
  852.     return bRet;  
  853. }  
  854.   
  855. // 缩放图像(指定缩放后图像的宽度和高度)  
  856. BOOL CWFBitmap::Zoom(  
  857.     DWORD dwNewWidth,          // 缩放后图像宽度  
  858.     DWORD dwNewHeight          // 缩放后图像高度  
  859.     )  
  860. {  
  861.     // 缩放后新IImage  
  862.     IImage *pNewImage = NULL;     
  863.     if (ZoomToIImage(pNewImage, dwNewWidth, dwNewHeight) == FALSE)  
  864.     {  
  865.         return FALSE;  
  866.     }     
  867.   
  868.     // 是否得到缩放后的IImage  
  869.     BOOL bRet = (pNewImage!=NULL) ? TRUE : FALSE;  
  870.   
  871.     // 改变IImage对象内容  
  872.     if (pNewImage != NULL)  
  873.     {  
  874.         // 释放原有的IImage  
  875.         Release();  
  876.   
  877.         // 得到新的IImage  
  878.         m_pImage = pNewImage;  
  879.   
  880.         // 得到新的ImageInfo      
  881.         m_pImage->GetImageInfo(&m_ImageInfo);  
  882.     }  
  883.   
  884.     // 返回结果  
  885.     return bRet;  
  886. }  
  887.   
  888. // 缩放图像到目标对象中(指定缩放后图像的宽度和高度),不改变对象自身  
  889. BOOL CWFBitmap::Zoom(  
  890.     CWFBitmap &dstBitmap,      // 带出缩放后的图像  
  891.     DWORD dwNewWidth,          // 缩放后图像宽度  
  892.     DWORD dwNewHeight          // 缩放后图像高度  
  893.     )  
  894. {  
  895.     // 缩放后新IImage  
  896.     IImage *pNewImage = NULL;     
  897.     if (ZoomToIImage(pNewImage, dwNewWidth, dwNewHeight) == FALSE)  
  898.     {  
  899.         return FALSE;  
  900.     }     
  901.   
  902.     // 通过IImage对象加载  
  903.     BOOL bRet = dstBitmap.LoadFromIImage(pNewImage);  
  904.   
  905.     // 释放缩放后对象  
  906.     if (pNewImage != NULL)  
  907.     {  
  908.         pNewImage->Release();  
  909.         pNewImage = NULL;  
  910.     }  
  911.   
  912.     // 返回缩放结果  
  913.     return bRet;  
  914. }  
  915.   
  916. // 缩放图像(指定缩放X方向,Y方向缩放比率)  
  917. BOOL CWFBitmap::ZoomEx(  
  918.     double dbZoomXRatio,       // X方向缩放率  
  919.     double dbZoomYRatio        // Y方向缩放率  
  920.     )  
  921. {  
  922.     // 计算缩放后图像宽度高度  
  923.     DWORD dwNewW = (DWORD)((double)m_ImageInfo.Width * dbZoomXRatio);  
  924.     DWORD dwNewH = (DWORD)((double)m_ImageInfo.Height * dbZoomYRatio);  
  925.     return Zoom(dwNewW, dwNewH);  
  926. }  
  927.   
  928. // 缩放图像到目标对象中(指定缩放X方向,Y方向缩放比率),不改变对象自身  
  929. BOOL CWFBitmap::ZoomEx(  
  930.     CWFBitmap &dstBitmap,      // 带出缩放后的图像  
  931.     double dbZoomXRatio,       // X方向缩放率  
  932.     double dbZoomYRatio        // Y方向缩放率  
  933.     )  
  934. {  
  935.     // 计算缩放后图像宽度高度  
  936.     DWORD dwNewW = (DWORD)((double)m_ImageInfo.Width * dbZoomXRatio);  
  937.     DWORD dwNewH = (DWORD)((double)m_ImageInfo.Height * dbZoomYRatio);  
  938.     return Zoom(dstBitmap, dwNewW, dwNewH);  
  939. }  
  940.   
  941. // 按特定角度旋转图像到IImage对象中,不改变自身数据  
  942. // 顺时针旋转,只支持90, 180, 270, or 360  
  943. BOOL CWFBitmap::RotateSpecificAngleToIImage(  
  944.     PWFIImage &pDstIImage,     // 存放旋转后图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放  
  945.     float fSpecificAngle       // 特定旋转角度(单位:度)  
  946.     )  
  947. {  
  948.     // 释放目标IImage对象  
  949.     if (pDstIImage != NULL)  
  950.     {  
  951.         pDstIImage->Release();  
  952.         pDstIImage = NULL;  
  953.     }  
  954.   
  955.     // 参数有效性  
  956.     if (m_pImage==NULL || m_pImagingFactory==NULL)  
  957.     {  
  958.         return FALSE;  
  959.     }  
  960.   
  961.     // 使用到的临时变量,由于后面使用了goto在此处定义  
  962.     BOOL bRet = TRUE;                       // 函数返回值  
  963.     IBitmapImage *pBmp = NULL;              // 位图接口  
  964.     IBitmapImage *pNewBmp = NULL;           // 缩放后位图接口  
  965.     IBasicBitmapOps *pBmpOps = NULL;        // 位图操作接口  
  966.   
  967.     // 得到位图接口     
  968.     HRESULT hr = m_pImagingFactory->CreateBitmapFromImage(m_pImage, m_ImageInfo.Width, m_ImageInfo.Height, m_ImageInfo.PixelFormat, InterpolationHintDefault, &pBmp);  
  969.     if (FAILED(hr))  
  970.     {  
  971.         printf("RotateSpecificAngleToIImage CreateBitmapFromImage Error!\n");  
  972.         bRet = FALSE;  
  973.         goto ERROR_END_FUNCTIONFLAG;  
  974.     }  
  975.   
  976.     // 得到位图操作接口   
  977.     hr = pBmp->QueryInterface(IID_IBasicBitmapOps,(void **)&pBmpOps);  
  978.     if (FAILED(hr))  
  979.     {  
  980.         printf("RotateSpecificAngleToIImage QueryInterface IID_IBasicBitmapOps Error!\n");  
  981.         bRet = FALSE;  
  982.         goto ERROR_END_FUNCTIONFLAG;          
  983.     }  
  984.   
  985.     // 旋转位图  
  986.     hr = pBmpOps->Rotate(fSpecificAngle, InterpolationHintDefault, &pNewBmp);  
  987.     if (FAILED(hr))  
  988.     {  
  989.         printf("RotateSpecificAngleToIImage Rotate Error!\n");  
  990.         bRet = FALSE;  
  991.         goto ERROR_END_FUNCTIONFLAG;  
  992.     }  
  993.   
  994.     // 得到新IImage  
  995.     hr = pNewBmp->QueryInterface(IID_IImage,(void **)&pDstIImage);  
  996.     if (FAILED(hr))  
  997.     {  
  998.         printf("RotateSpecificAngleToIImage QueryInterface pDstIImage Error!\n");  
  999.         bRet = FALSE;  
  1000.         goto ERROR_END_FUNCTIONFLAG;  
  1001.     }  
  1002.   
  1003.     // 正确得到旋转后的IImage  
  1004.     bRet = TRUE;  
  1005.   
  1006.     // 进入释放过程  
  1007. ERROR_END_FUNCTIONFLAG:  
  1008.     // 释放位图  
  1009.     if (pBmp != NULL)  
  1010.     {  
  1011.         pBmp->Release();  
  1012.         pBmp = NULL;  
  1013.     }  
  1014.   
  1015.     // 释放缩放后位图  
  1016.     if (pNewBmp != NULL)  
  1017.     {  
  1018.         pNewBmp->Release();  
  1019.         pNewBmp = NULL;  
  1020.     }  
  1021.   
  1022.     // 释放位图操作接口  
  1023.     if (pBmpOps != NULL)  
  1024.     {  
  1025.         pBmpOps->Release();  
  1026.         pBmpOps = NULL;  
  1027.     }  
  1028.   
  1029.     // 返回结果  
  1030.     return bRet;  
  1031. }  
  1032.   
  1033. // 按特定角度旋转图像  
  1034. // 顺时针旋转,只支持90, 180, 270, or 360  
  1035. BOOL CWFBitmap::RotateSpecificAngle(  
  1036.     float fSpecificAngle       // 特定旋转角度(单位:度)  
  1037.     )  
  1038. {  
  1039.     // 旋转后新IImage  
  1040.     IImage *pNewImage = NULL;     
  1041.     if (RotateSpecificAngleToIImage(pNewImage, fSpecificAngle) == FALSE)  
  1042.     {  
  1043.         return FALSE;  
  1044.     }     
  1045.   
  1046.     // 是否得到旋转后的IImage  
  1047.     BOOL bRet = (pNewImage!=NULL) ? TRUE : FALSE;  
  1048.   
  1049.     // 改变IImage对象内容  
  1050.     if (pNewImage != NULL)  
  1051.     {  
  1052.         // 释放原有的IImage  
  1053.         Release();  
  1054.   
  1055.         // 得到新的IImage  
  1056.         m_pImage = pNewImage;  
  1057.   
  1058.         // 得到新的ImageInfo      
  1059.         m_pImage->GetImageInfo(&m_ImageInfo);  
  1060.     }  
  1061.   
  1062.     // 返回结果  
  1063.     return bRet;  
  1064. }  
  1065.   
  1066. // 按特定角度旋转图像到目标对象中,不改变对象自身  
  1067. // 顺时针旋转,只支持90, 180, 270, or 360  
  1068. BOOL CWFBitmap::RotateSpecificAngle(  
  1069.     CWFBitmap &dstBitmap,      // 带出旋转后的图像  
  1070.     float fSpecificAngle       // 特定旋转角度(单位:度)  
  1071.     )  
  1072. {  
  1073.     // 旋转后新IImage  
  1074.     IImage *pNewImage = NULL;     
  1075.     if (RotateSpecificAngleToIImage(pNewImage, fSpecificAngle) == FALSE)  
  1076.     {  
  1077.         return FALSE;  
  1078.     }     
  1079.   
  1080.     // 通过IImage对象加载  
  1081.     BOOL bRet = dstBitmap.LoadFromIImage(pNewImage);  
  1082.   
  1083.     // 释放旋转后对象  
  1084.     if (pNewImage != NULL)  
  1085.     {  
  1086.         pNewImage->Release();  
  1087.         pNewImage = NULL;  
  1088.     }  
  1089.   
  1090.     // 返回旋转结果  
  1091.     return bRet;  
  1092. }  
  1093.   
  1094. // 翻转图像到IImage对象中,不改变自身数据  
  1095. BOOL CWFBitmap::FlipToIImage(  
  1096.     PWFIImage &pDstIImage,     // 存放翻转后图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放  
  1097.     BOOL bFilpX,               // 是否反转X方向  
  1098.     BOOL bFlipY                // 是否反转Y方向  
  1099.     )  
  1100. {  
  1101.     // 释放目标IImage对象  
  1102.     if (pDstIImage != NULL)  
  1103.     {  
  1104.         pDstIImage->Release();  
  1105.         pDstIImage = NULL;  
  1106.     }  
  1107.   
  1108.     // 参数有效性  
  1109.     if (m_pImage==NULL || m_pImagingFactory==NULL)  
  1110.     {  
  1111.         return FALSE;  
  1112.     }  
  1113.   
  1114.     // 使用到的临时变量,由于后面使用了goto在此处定义  
  1115.     BOOL bRet = TRUE;                       // 函数返回值  
  1116.     IBitmapImage *pBmp = NULL;              // 位图接口  
  1117.     IBitmapImage *pNewBmp = NULL;           // 缩放后位图接口  
  1118.     IBasicBitmapOps *pBmpOps = NULL;        // 位图操作接口  
  1119.   
  1120.     // 得到位图接口     
  1121.     HRESULT hr = m_pImagingFactory->CreateBitmapFromImage(m_pImage, m_ImageInfo.Width, m_ImageInfo.Height, m_ImageInfo.PixelFormat, InterpolationHintDefault, &pBmp);  
  1122.     if (FAILED(hr))  
  1123.     {  
  1124.         printf("FlipToIImage CreateBitmapFromImage Error!\n");  
  1125.         bRet = FALSE;  
  1126.         goto ERROR_END_FUNCTIONFLAG;  
  1127.     }  
  1128.   
  1129.     // 得到位图操作接口   
  1130.     hr = pBmp->QueryInterface(IID_IBasicBitmapOps,(void **)&pBmpOps);  
  1131.     if (FAILED(hr))  
  1132.     {  
  1133.         printf("FlipToIImage QueryInterface IID_IBasicBitmapOps Error!\n");  
  1134.         bRet = FALSE;  
  1135.         goto ERROR_END_FUNCTIONFLAG;          
  1136.     }  
  1137.   
  1138.     // 翻转位图  
  1139.     hr = pBmpOps->Flip(bFilpX, bFlipY, &pNewBmp);  
  1140.     if (FAILED(hr))  
  1141.     {  
  1142.         printf("FlipToIImage Flip Error!\n");  
  1143.         bRet = FALSE;  
  1144.         goto ERROR_END_FUNCTIONFLAG;  
  1145.     }  
  1146.   
  1147.     // 得到新IImage  
  1148.     hr = pNewBmp->QueryInterface(IID_IImage,(void **)&pDstIImage);  
  1149.     if (FAILED(hr))  
  1150.     {  
  1151.         printf("FlipToIImage QueryInterface pDstIImage Error!\n");  
  1152.         bRet = FALSE;  
  1153.         goto ERROR_END_FUNCTIONFLAG;  
  1154.     }  
  1155.   
  1156.     // 正确得到翻转后的IImage  
  1157.     bRet = TRUE;  
  1158.   
  1159.     // 进入释放过程  
  1160. ERROR_END_FUNCTIONFLAG:  
  1161.     // 释放位图  
  1162.     if (pBmp != NULL)  
  1163.     {  
  1164.         pBmp->Release();  
  1165.         pBmp = NULL;  
  1166.     }  
  1167.   
  1168.     // 释放缩放后位图  
  1169.     if (pNewBmp != NULL)  
  1170.     {  
  1171.         pNewBmp->Release();  
  1172.         pNewBmp = NULL;  
  1173.     }  
  1174.   
  1175.     // 释放位图操作接口  
  1176.     if (pBmpOps != NULL)  
  1177.     {  
  1178.         pBmpOps->Release();  
  1179.         pBmpOps = NULL;  
  1180.     }  
  1181.   
  1182.     // 返回结果  
  1183.     return bRet;  
  1184. }  
  1185.   
  1186. // 翻转图像  
  1187. BOOL CWFBitmap::Flip(  
  1188.     BOOL bFilpX,               // 是否反转X方向  
  1189.     BOOL bFlipY                // 是否反转Y方向  
  1190.     )  
  1191. {  
  1192.     // 翻转后新IImage  
  1193.     IImage *pNewImage = NULL;     
  1194.     if (FlipToIImage(pNewImage, bFilpX, bFlipY) == FALSE)  
  1195.     {  
  1196.         return FALSE;  
  1197.     }     
  1198.   
  1199.     // 是否得到翻转后的IImage  
  1200.     BOOL bRet = (pNewImage!=NULL) ? TRUE : FALSE;  
  1201.   
  1202.     // 改变IImage对象内容  
  1203.     if (pNewImage != NULL)  
  1204.     {  
  1205.         // 释放原有的IImage  
  1206.         Release();  
  1207.   
  1208.         // 得到新的IImage  
  1209.         m_pImage = pNewImage;  
  1210.   
  1211.         // 得到新的ImageInfo      
  1212.         m_pImage->GetImageInfo(&m_ImageInfo);  
  1213.     }  
  1214.   
  1215.     // 返回结果  
  1216.     return bRet;  
  1217. }  
  1218.   
  1219. // 翻转图像到目标对象中,不改变对象自身  
  1220. BOOL CWFBitmap::Flip(  
  1221.     CWFBitmap &dstBitmap,      // 带出翻转后的图像  
  1222.     BOOL bFilpX,               // 是否反转X方向  
  1223.     BOOL bFlipY                // 是否反转Y方向  
  1224.     )  
  1225. {  
  1226.     // 翻转后新IImage  
  1227.     IImage *pNewImage = NULL;     
  1228.     if (FlipToIImage(pNewImage, bFilpX, bFlipY) == FALSE)  
  1229.     {  
  1230.         return FALSE;  
  1231.     }     
  1232.   
  1233.     // 通过IImage对象加载  
  1234.     BOOL bRet = dstBitmap.LoadFromIImage(pNewImage);  
  1235.   
  1236.     // 释放翻转后对象  
  1237.     if (pNewImage != NULL)  
  1238.     {  
  1239.         pNewImage->Release();  
  1240.         pNewImage = NULL;  
  1241.     }  
  1242.   
  1243.     // 返回翻转结果  
  1244.     return bRet;  
  1245. }  
  1246.   
  1247. // 裁剪图像上指定区域到IImage对象中,不改变自身数据  
  1248. BOOL CWFBitmap::CutToIImage(  
  1249.     PWFIImage &pDstIImage,     // 存放裁剪图像的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放  
  1250.     const RECT *pCutRect       // 在图像上裁剪的区域  
  1251.     )  
  1252. {  
  1253.     // 释放目标IImage对象  
  1254.     if (pDstIImage != NULL)  
  1255.     {  
  1256.         pDstIImage->Release();  
  1257.         pDstIImage = NULL;  
  1258.     }  
  1259.   
  1260.     // 参数有效性  
  1261.     if (m_pImage==NULL || m_pImagingFactory==NULL || pCutRect==NULL)  
  1262.     {  
  1263.         return FALSE;  
  1264.     }  
  1265.   
  1266.     // 裁剪区域有效性  
  1267.     if (pCutRect->left>=pCutRect->right || pCutRect->top>=pCutRect->bottom)  
  1268.     {  
  1269.         printf("CutToIImage CurRect Error!\n");  
  1270.         return FALSE;  
  1271.     }  
  1272.   
  1273.     // 使用到的临时变量,由于后面使用了goto在此处定义  
  1274.     BOOL bRet = TRUE;                       // 函数返回值  
  1275.     IBitmapImage *pBmp = NULL;              // 位图接口  
  1276.     IBitmapImage *pNewBmp = NULL;           // 缩放后位图接口  
  1277.     IBasicBitmapOps *pBmpOps = NULL;        // 位图操作接口  
  1278.   
  1279.     // 得到位图接口     
  1280.     HRESULT hr = m_pImagingFactory->CreateBitmapFromImage(m_pImage, m_ImageInfo.Width, m_ImageInfo.Height, m_ImageInfo.PixelFormat, InterpolationHintDefault, &pBmp);  
  1281.     if (FAILED(hr))  
  1282.     {  
  1283.         printf("CutToIImage CreateBitmapFromImage Error!\n");  
  1284.         bRet = FALSE;  
  1285.         goto ERROR_END_FUNCTIONFLAG;  
  1286.     }  
  1287.   
  1288.     // 得到位图操作接口   
  1289.     hr = pBmp->QueryInterface(IID_IBasicBitmapOps,(void **)&pBmpOps);  
  1290.     if (FAILED(hr))  
  1291.     {  
  1292.         printf("CutToIImage QueryInterface IID_IBasicBitmapOps Error!\n");  
  1293.         bRet = FALSE;  
  1294.         goto ERROR_END_FUNCTIONFLAG;          
  1295.     }  
  1296.   
  1297.     // 翻转位图  
  1298.     hr = pBmpOps->Clone(pCutRect, &pNewBmp, TRUE);     
  1299.     if (FAILED(hr))  
  1300.     {   
  1301.         printf("CutToIImage Clone Error!\n");  
  1302.         bRet = FALSE;  
  1303.         goto ERROR_END_FUNCTIONFLAG;  
  1304.     }  
  1305.   
  1306.     // 得到新IImage  
  1307.     hr = pNewBmp->QueryInterface(IID_IImage,(void **)&pDstIImage);  
  1308.     if (FAILED(hr))  
  1309.     {  
  1310.         printf("CutToIImage QueryInterface pDstIImage Error!\n");  
  1311.         bRet = FALSE;  
  1312.         goto ERROR_END_FUNCTIONFLAG;  
  1313.     }  
  1314.   
  1315.     // 正确得到裁剪的IImage  
  1316.     bRet = TRUE;  
  1317.   
  1318.     // 进入释放过程  
  1319. ERROR_END_FUNCTIONFLAG:  
  1320.     // 释放位图  
  1321.     if (pBmp != NULL)  
  1322.     {  
  1323.         pBmp->Release();  
  1324.         pBmp = NULL;  
  1325.     }  
  1326.   
  1327.     // 释放缩放后位图  
  1328.     if (pNewBmp != NULL)  
  1329.     {  
  1330.         pNewBmp->Release();  
  1331.         pNewBmp = NULL;  
  1332.     }  
  1333.   
  1334.     // 释放位图操作接口  
  1335.     if (pBmpOps != NULL)  
  1336.     {  
  1337.         pBmpOps->Release();  
  1338.         pBmpOps = NULL;  
  1339.     }  
  1340.   
  1341.     // 返回结果  
  1342.     return bRet;  
  1343. }  
  1344.   
  1345. // 裁剪图像(图像改变为指定裁剪区域的图像)  
  1346. BOOL CWFBitmap::Cut(  
  1347.     const RECT *pCutRect       // 在图像上裁剪的区域  
  1348.     )  
  1349. {  
  1350.     // 裁剪到的新IImage  
  1351.     IImage *pNewImage = NULL;     
  1352.     if (CutToIImage(pNewImage, pCutRect) == FALSE)  
  1353.     {  
  1354.         return FALSE;  
  1355.     }     
  1356.   
  1357.     // 是否得到裁剪的IImage  
  1358.     BOOL bRet = (pNewImage!=NULL) ? TRUE : FALSE;  
  1359.   
  1360.     // 改变IImage对象内容  
  1361.     if (pNewImage != NULL)  
  1362.     {  
  1363.         // 释放原有的IImage  
  1364.         Release();  
  1365.   
  1366.         // 得到新的IImage  
  1367.         m_pImage = pNewImage;  
  1368.   
  1369.         // 得到新的ImageInfo      
  1370.         m_pImage->GetImageInfo(&m_ImageInfo);  
  1371.     }  
  1372.   
  1373.     // 返回结果  
  1374.     return bRet;  
  1375. }  
  1376.   
  1377. // 裁剪图像到目标对象中,不改变对象自身  
  1378. BOOL CWFBitmap::Cut(  
  1379.     CWFBitmap &dstBitmap,      // 带出裁剪到的图像  
  1380.     const RECT *pCutRect       // 在图像上裁剪的区域  
  1381.     )  
  1382. {  
  1383.     // 裁剪到的IImage  
  1384.     IImage *pNewImage = NULL;     
  1385.     if (CutToIImage(pNewImage, pCutRect) == FALSE)  
  1386.     {  
  1387.         return FALSE;  
  1388.     }     
  1389.   
  1390.     // 通过IImage对象加载  
  1391.     BOOL bRet = dstBitmap.LoadFromIImage(pNewImage);  
  1392.   
  1393.     // 释放新的对象  
  1394.     if (pNewImage != NULL)  
  1395.     {  
  1396.         pNewImage->Release();  
  1397.         pNewImage = NULL;  
  1398.     }  
  1399.   
  1400.     // 返回结果  
  1401.     return bRet;  
  1402. }  
  1403.   
  1404. // 生成缩略图到指定IImage对象中,不改变自身数据  
  1405. BOOL CWFBitmap::ThumbnailToIImage(  
  1406.     PWFIImage &pDstIImage,     // 存放缩略图的IImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放  
  1407.     DWORD dwThumbWidth,        // 缩略图宽度  
  1408.     DWORD dwThumbHeight        // 缩略图高度  
  1409.     )  
  1410. {  
  1411.     // 释放目标IImage对象  
  1412.     if (pDstIImage != NULL)  
  1413.     {  
  1414.         pDstIImage->Release();  
  1415.         pDstIImage = NULL;  
  1416.     }  
  1417.   
  1418.     // 参数有效性  
  1419.     if (m_pImage==NULL || dwThumbWidth==0 || dwThumbHeight==0)  
  1420.     {  
  1421.         return FALSE;  
  1422.     }  
  1423.   
  1424.     // 得到缩略图  
  1425.     HRESULT hr = m_pImage->GetThumbnail(dwThumbWidth, dwThumbHeight, &pDstIImage);  
  1426.     if (FAILED(hr))  
  1427.     {  
  1428.         printf("ThumbnailToIImage GetThumbnail Error!\n");  
  1429.         return FALSE;  
  1430.     }  
  1431.   
  1432.     // 得到缩略图  
  1433.     return TRUE;  
  1434. }  
  1435.   
  1436. // 生成缩略图(图像改变为缩略图)  
  1437. BOOL CWFBitmap::Thumbnail(  
  1438.     DWORD dwThumbWidth,        // 缩略图宽度  
  1439.     DWORD dwThumbHeight        // 缩略图高度  
  1440.     )  
  1441. {  
  1442.     // 得到新的IImage  
  1443.     IImage *pNewImage = NULL;     
  1444.     if (ThumbnailToIImage(pNewImage, dwThumbWidth, dwThumbHeight) == FALSE)  
  1445.     {  
  1446.         return FALSE;  
  1447.     }     
  1448.   
  1449.     // 是否得到新的IImage  
  1450.     BOOL bRet = (pNewImage!=NULL) ? TRUE : FALSE;  
  1451.   
  1452.     // 改变IImage对象内容  
  1453.     if (pNewImage != NULL)  
  1454.     {  
  1455.         // 释放原有的IImage  
  1456.         Release();  
  1457.   
  1458.         // 得到新的IImage  
  1459.         m_pImage = pNewImage;  
  1460.   
  1461.         // 得到新的ImageInfo      
  1462.         m_pImage->GetImageInfo(&m_ImageInfo);  
  1463.     }  
  1464.   
  1465.     // 返回结果  
  1466.     return bRet;  
  1467. }  
  1468.   
  1469. // 生成缩略图(指定缩放比率)(图像改变为缩略图)  
  1470. BOOL CWFBitmap::ThumbnailEx(  
  1471.     double dbXRatio,           // X方向缩放率  
  1472.     double dbYRatio            // Y方向缩放率  
  1473.     )  
  1474. {  
  1475.     // 计算缩放后图像宽度高度  
  1476.     DWORD dwNewW = (DWORD)((double)m_ImageInfo.Width * dbXRatio);  
  1477.     DWORD dwNewH = (DWORD)((double)m_ImageInfo.Height * dbYRatio);  
  1478.     return Thumbnail(dwNewW, dwNewH);  
  1479. }  
  1480.   
  1481. // 生成缩略图到目标对象中,不改变对象自身  
  1482. BOOL CWFBitmap::Thumbnail(  
  1483.     CWFBitmap &dstBitmap,      // 带出旋转后的图像  
  1484.     DWORD dwThumbWidth,        // 缩略图宽度  
  1485.     DWORD dwThumbHeight        // 缩略图高度  
  1486.     )  
  1487. {  
  1488.     // 得到新的IImage  
  1489.     IImage *pNewImage = NULL;     
  1490.     if (ThumbnailToIImage(pNewImage, dwThumbWidth, dwThumbHeight) == FALSE)  
  1491.     {  
  1492.         return FALSE;  
  1493.     }     
  1494.   
  1495.     // 通过IImage对象加载  
  1496.     BOOL bRet = dstBitmap.LoadFromIImage(pNewImage);  
  1497.   
  1498.     // 释放新的对象  
  1499.     if (pNewImage != NULL)  
  1500.     {  
  1501.         pNewImage->Release();  
  1502.         pNewImage = NULL;  
  1503.     }  
  1504.   
  1505.     // 返回结果  
  1506.     return bRet;  
  1507. }  
  1508.   
  1509. // 生成缩略图到目标对象中(指定缩放比率),不改变对象自身  
  1510. BOOL CWFBitmap::ThumbnailEx(  
  1511.     CWFBitmap &dstBitmap,      // 带出旋转后的图像  
  1512.     double dbXRatio,           // X方向缩放率  
  1513.     double dbYRatio            // Y方向缩放率  
  1514.     )  
  1515. {  
  1516.     // 计算缩放后图像宽度高度  
  1517.     DWORD dwNewW = (DWORD)((double)m_ImageInfo.Width * dbXRatio);  
  1518.     DWORD dwNewH = (DWORD)((double)m_ImageInfo.Height * dbYRatio);  
  1519.     return Thumbnail(dstBitmap, dwNewW, dwNewH);  
  1520. }  
  1521.   
  1522. // 图像旋转任意角度到IBitmapImage对象中,不改变自身数据  
  1523. // 若只需要旋转90,180,270,360请调用接口RotateSpecificAngleToIImage   
  1524. BOOL CWFBitmap::RotateToIBitmapImage(  
  1525.     PWFIBitmapImage &pDstIBitmapImage,     // 存放旋转后图像的IBitmapImage,外部传入若不是NULL内部会释放,带出的结果需要外部释放  
  1526.     float fAngle                           // 特定旋转角度(单位:度)  
  1527.     )  
  1528. {     
  1529.     // 释放目标IImage对象  
  1530.     if (pDstIBitmapImage != NULL)  
  1531.     {  
  1532.         pDstIBitmapImage->Release();  
  1533.         pDstIBitmapImage = NULL;  
  1534.     }  
  1535.   
  1536.     // 参数有效性  
  1537.     if (m_pImage==NULL || m_pImagingFactory==NULL)  
  1538.     {  
  1539.         return FALSE;  
  1540.     }  
  1541.   
  1542.     // 得到图片数据区  
  1543.     if (CreateImgDateBuf() == FALSE)  
  1544.     {  
  1545.         return FALSE;  
  1546.     }  
  1547.   
  1548.     // 旋转图像数据缓冲区  
  1549.     PWFBYTE pDstBuf = NULL;  
  1550.     DWORD dwDstWidth = 0;  
  1551.     DWORD dwDstHeight = 0;  
  1552.     if (WFBING_RotateImageBuffer(  
  1553.                               m_pImgDataBuf,   
  1554.                               m_ImageInfo.Width,   
  1555.                               m_ImageInfo.Height,   
  1556.                               (double)fAngle,  
  1557.                               pDstBuf,   
  1558.                               dwDstWidth,   
  1559.                               dwDstHeight  
  1560.                               ) == FALSE)  
  1561.     {  
  1562.         return FALSE;  
  1563.     }  
  1564.   
  1565.     // 由于CreateBitmapFromBuffer创建时需要自己管理内存,对于CWFBitmap对象间的赋值拷贝不容易处理  
  1566.     // 此处使用CreateNewBitmap创建新的位图,把得到旋转后的数据强制写入,管理此IBitmapImage即可  
  1567.     // 用于锁定位图数据  
  1568.     BitmapData bitmapData;    
  1569.     bitmapData.Width = dwDstWidth;    
  1570.     bitmapData.Height = dwDstHeight;    
  1571.     bitmapData.PixelFormat = PIXFMT_32BPP_ARGB;   
  1572.     RECT rect = {0, 0, dwDstWidth, dwDstHeight};   
  1573.   
  1574.     // 创建新的位图  
  1575.     HRESULT hr = m_pImagingFactory->CreateNewBitmap(dwDstWidth, dwDstHeight, PIXFMT_32BPP_ARGB, &pDstIBitmapImage);  
  1576.     BOOL bRet = FALSE;  
  1577.     if (FAILED(hr))  
  1578.     {  
  1579.         bRet = FALSE;  
  1580.         goto THEEND_FOR_THISFOUNCTION;  
  1581.     }  
  1582.   
  1583.     // 锁定位图数据      
  1584.     hr = pDstIBitmapImage->LockBits(&rect, ImageLockModeRead, PIXFMT_32BPP_ARGB, &bitmapData);    
  1585.     if (FAILED(hr))  
  1586.     {  
  1587.         bRet = FALSE;  
  1588.         goto THEEND_FOR_THISFOUNCTION;        
  1589.     }  
  1590.   
  1591.     // 把旋转后数据写入位图  
  1592.     BYTE *pBmpBuf = (BYTE*)bitmapData.Scan0;  
  1593.     memcpy(pBmpBuf, pDstBuf, dwDstWidth*dwDstHeight*4);  
  1594.   
  1595.     // 释放锁定位图数据  
  1596.     pDstIBitmapImage->UnlockBits(&bitmapData);  
  1597.   
  1598.     // 写入成功  
  1599.     bRet = TRUE;      
  1600.   
  1601. THEEND_FOR_THISFOUNCTION:  
  1602.     // 释放临时存放旋转后  
  1603.     if (pDstBuf != NULL)  
  1604.     {  
  1605.         delete[] pDstBuf;  
  1606.         pDstBuf = NULL;  
  1607.     }  
  1608.   
  1609.     // 释放IBitmapImage对象  
  1610.     if (bRet==FALSE && pDstIBitmapImage!=NULL)  
  1611.     {  
  1612.         pDstIBitmapImage->Release();  
  1613.         pDstIBitmapImage = NULL;  
  1614.     }  
  1615.   
  1616.     // 返回结果  
  1617.     return bRet;  
  1618. }  
  1619.   
  1620. // 按任意角度旋转图像      
  1621. // 若只需要旋转90,180,270,360请调用接口RotateSpecificAngle  
  1622. BOOL CWFBitmap::Rotate(  
  1623.     float fAngle               // 特定旋转角度(单位:度)  
  1624.     )  
  1625. {  
  1626.     // 得到新的IBitmapImage  
  1627.     IBitmapImage *pNewBitmapImage = NULL;     
  1628.     if (RotateToIBitmapImage(pNewBitmapImage, fAngle) == FALSE)  
  1629.     {  
  1630.         return FALSE;  
  1631.     }     
  1632.   
  1633.     // 是否得到新的IImage  
  1634.     BOOL bRet = (pNewBitmapImage!=NULL) ? TRUE : FALSE;  
  1635.   
  1636.     // 改变IImage对象内容  
  1637.     if (pNewBitmapImage != NULL)  
  1638.     {  
  1639.         // 释放原有的IImage  
  1640.         Release();  
  1641.   
  1642.         // 得到IBitmapImage  
  1643.         m_pBitmapImage = pNewBitmapImage;  
  1644.   
  1645.         // 得到新的IImage  
  1646.         m_pBitmapImage->QueryInterface(IID_IImage, (void**)&m_pImage);  
  1647.           
  1648.         // 得到新的ImageInfo      
  1649.         if (m_pImage != NULL)  
  1650.         {  
  1651.             m_pImage->GetImageInfo(&m_ImageInfo);  
  1652.         }         
  1653.     }  
  1654.   
  1655.     // 返回结果  
  1656.     return bRet;      
  1657. }  
  1658.   
  1659. // 按任意角度旋转图像到目标对象中,不改变对象自身  
  1660. // 若只需要旋转90,180,270,360请调用接口RotateSpecificAngle  
  1661. BOOL CWFBitmap::Rotate(  
  1662.     CWFBitmap &dstBitmap,      // 带出旋转后的图像  
  1663.     float fAngle               // 特定旋转角度(单位:度)  
  1664.     )  
  1665. {  
  1666.     // 得到新的IBitmapImage  
  1667.     IBitmapImage *pNewBitmapImage = NULL;     
  1668.     if (RotateToIBitmapImage(pNewBitmapImage, fAngle) == FALSE)  
  1669.     {  
  1670.         return FALSE;  
  1671.     }     
  1672.   
  1673.     // 通过IImage对象加载  
  1674.     BOOL bRet = dstBitmap.LoadFromIBitmapImage(pNewBitmapImage);  
  1675.   
  1676.     // 释放新的对象  
  1677.     if (pNewBitmapImage != NULL)  
  1678.     {  
  1679.         pNewBitmapImage->Release();  
  1680.         pNewBitmapImage = NULL;  
  1681.     }  
  1682.   
  1683.     // 返回结果  
  1684.     return bRet;      
  1685. }  
  1686.   
  1687. // 获得图像数据(只含有各个点的颜色信息)  
  1688. BOOL CWFBitmap::GetColorBuf(  
  1689.     unsigned char *pDataBuf,           // 存放图像数据缓冲区  
  1690.     DWORD dwcbBufSize,                 // 缓冲区实际大小(需要的大小通常是(宽度*高度*4))  
  1691.     DWORD *pdwRealGetBytes             // 实际取得数据字节大小  
  1692.     )  
  1693. {  
  1694.     // 参数有效性  
  1695.     if (pDataBuf==NULL || dwcbBufSize==0)  
  1696.     {  
  1697.         return FALSE;  
  1698.     }  
  1699.   
  1700.     // 获取原始数据失败  
  1701.     if (CreateImgDateBuf() == FALSE)  
  1702.     {  
  1703.         return FALSE;  
  1704.     }     
  1705.   
  1706.     // 计算实际取得数据字节大小  
  1707.     DWORD dwRealBytes = (dwcbBufSize < m_dwcbImgDataBufSize) ? dwcbBufSize : m_dwcbImgDataBufSize;  
  1708.     if (dwRealBytes == 0)  
  1709.     {  
  1710.         return FALSE;  
  1711.     }  
  1712.   
  1713.     // 拷贝数据  
  1714.     memcpy(pDataBuf, m_pImgDataBuf, dwRealBytes);  
  1715.   
  1716.     // 带出实际拷贝数据字节数  
  1717.     if (pdwRealGetBytes != NULL)  
  1718.     {  
  1719.         *pdwRealGetBytes = dwRealBytes;  
  1720.     }  
  1721.   
  1722.     // 取得数据成功  
  1723.     return TRUE;  
  1724. }  
  1725.   
  1726. // 获得图片数据(只含有各个点的颜色信息)缓冲区地址,返回NULL表示没有图片数据  
  1727. const unsigned char* CWFBitmap::GetColorBufAddr(  
  1728.     DWORD *pdwcbBufSize          // 带出颜色缓冲区字节大小  
  1729.     )  
  1730. {  
  1731.     // 初始化输出参数  
  1732.     if (pdwcbBufSize != NULL)  
  1733.     {  
  1734.         *pdwcbBufSize = 0;  
  1735.     }  
  1736.   
  1737.     // 获取原始数据失败  
  1738.     if (CreateImgDateBuf() == FALSE)  
  1739.     {  
  1740.         return NULL;  
  1741.     }     
  1742.   
  1743.     // 带出实际大小  
  1744.     if (pdwcbBufSize != NULL)  
  1745.     {  
  1746.         *pdwcbBufSize = m_dwcbImgDataBufSize;  
  1747.     }  
  1748.   
  1749.     // 返回地址  
  1750.     return m_pImgDataBuf;  
  1751. }  
  1752.   
  1753. //  
  1754. // 创建Image工厂接口对象  
  1755. BOOL CWFBitmap::CreateImagingFactory(void)  
  1756. {  
  1757.     // 已经创建了Image工厂接口对象  
  1758.     if (m_pImagingFactory != NULL)  
  1759.     {  
  1760.         m_dwObjCounts += 1;  
  1761.         return TRUE;  
  1762.     }  
  1763.   
  1764.     // 未创建则创建Image工厂接口对象  
  1765.     m_dwObjCounts = 0;  
  1766.   
  1767.     // COM初始化  
  1768.     HRESULT hr = NULL;  
  1769.     if (FAILED(hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED)))  
  1770.     {    
  1771.         return FALSE;  
  1772.     }  
  1773.   
  1774.     // 创建COM实例  
  1775.     if(FAILED(hr = ::CoCreateInstance(CLSID_ImagingFactory, NULL, CLSCTX_INPROC_SERVER, IID_IImagingFactory, (void**)&m_pImagingFactory)))  
  1776.     {         
  1777.         return FALSE;  
  1778.     }     
  1779.   
  1780.     // 创建成功数量增加  
  1781.     m_dwObjCounts += 1;   
  1782.     return TRUE;  
  1783. }  
  1784.   
  1785. // 释放Image工厂接口对象  
  1786. void CWFBitmap::DeleteImagingFactory(void)  
  1787. {  
  1788.     if (m_pImagingFactory!=NULL && m_dwObjCounts>0)  
  1789.     {  
  1790.         m_dwObjCounts -= 1;  
  1791.         if (m_dwObjCounts == 0)  
  1792.         {  
  1793.             // 释放ImagingFactory       
  1794.             m_pImagingFactory->Release();  
  1795.             m_pImagingFactory = NULL;             
  1796.   
  1797.             // 释放COM  
  1798.             ::CoUninitialize();  
  1799.         }         
  1800.     }  
  1801. }  
  1802.   
  1803. // 为图片创建内存DC  
  1804. HDC CWFBitmap::CreateImgDC(HDC hdc)  
  1805. {  
  1806.     if (m_hDrawDC != NULL)  
  1807.     {  
  1808.         return m_hDrawDC;  
  1809.     }  
  1810.   
  1811.     // 创建内存DC  
  1812.     m_hDrawDC = ::CreateCompatibleDC(hdc);            
  1813.     m_hBitmap = ::CreateCompatibleBitmap(hdc, m_ImageInfo.Width, m_ImageInfo.Height);  
  1814.     m_hOldBitmap = (HBITMAP)::SelectObject(m_hDrawDC, m_hBitmap);  
  1815.   
  1816.     // 填充背景为全黑色  
  1817.     ::PatBlt(m_hDrawDC, 0, 0, m_ImageInfo.Width, m_ImageInfo.Height, BLACKNESS);  
  1818.   
  1819.     // 绘制图像到内存DC上  
  1820.     RECT rcDc = {0, 0, m_ImageInfo.Width, m_ImageInfo.Height};  
  1821.     m_pImage->Draw(m_hDrawDC, &rcDc, NULL);  
  1822.     return m_hDrawDC;  
  1823. }  
  1824.   
  1825. // 清除内存DC  
  1826. void CWFBitmap::DeleteImgDC(void)  
  1827. {  
  1828.     if (m_hDrawDC != NULL)  
  1829.     {  
  1830.         ::SelectObject(m_hDrawDC, m_hOldBitmap);  
  1831.         ::DeleteObject(m_hBitmap);        
  1832.         ::DeleteDC(m_hDrawDC);  
  1833.         m_hDrawDC = NULL;  
  1834.         m_hBitmap = NULL;  
  1835.         m_hOldBitmap = NULL;  
  1836.     }  
  1837. }  
  1838.   
  1839. // 取得图片原始数据  
  1840. BOOL CWFBitmap::CreateImgDateBuf(void)  
  1841. {  
  1842.     // 已经获取到了原始数据  
  1843.     if (m_pImgDataBuf != NULL)  
  1844.     {     
  1845.         return TRUE;  
  1846.     }  
  1847.   
  1848.     // 参数有效性  
  1849.     if (m_pImage==NULL || m_pImagingFactory==NULL)  
  1850.     {         
  1851.         return FALSE;  
  1852.     }  
  1853.   
  1854.     // 取得图片原始数据  
  1855.     RECT rect = {0, 0, m_ImageInfo.Width, m_ImageInfo.Height};    
  1856.     BitmapData bitmapData;    
  1857.     bitmapData.Width = m_ImageInfo.Width;    
  1858.     bitmapData.Height = m_ImageInfo.Height;    
  1859.     bitmapData.PixelFormat = m_ImageInfo.PixelFormat;    
  1860.     IBitmapImage *pBitmapImage = NULL;    
  1861.     HRESULT hr = m_pImagingFactory->CreateBitmapFromImage(m_pImage, m_ImageInfo.Width, m_ImageInfo.Height, PIXFMT_32BPP_ARGB, InterpolationHintDefault, &pBitmapImage);    
  1862.     if (FAILED(hr))  
  1863.     {  
  1864.         printf("CreateImgDateBuf CreateBitmapFromImage Error!\n");  
  1865.         return FALSE;  
  1866.     }  
  1867.   
  1868.     // 锁定位图数据  
  1869.     hr = pBitmapImage->LockBits(&rect, ImageLockModeRead, PIXFMT_32BPP_ARGB, &bitmapData);    
  1870.     if (FAILED(hr))  
  1871.     {  
  1872.         printf("CreateImgDateBuf LockBits Error!\n");  
  1873.         pBitmapImage->Release();  
  1874.         return FALSE;  
  1875.     }  
  1876.   
  1877.     // 用于返回结果  
  1878.     BOOL bRet = TRUE;  
  1879.   
  1880.     // 得到数据字节大小  
  1881.     m_dwcbImgDataBufSize = m_ImageInfo.Width * m_ImageInfo.Height * 4;  
  1882.     if (m_dwcbImgDataBufSize == 0)  
  1883.     {  
  1884.         bRet = FALSE;  
  1885.         goto ERROR_END_FUNCTION;  
  1886.     }  
  1887.   
  1888.     // 申请新空间  
  1889.     bRet = TRUE;      
  1890.     m_pImgDataBuf = new unsigned char[m_dwcbImgDataBufSize];  
  1891.     if (m_pImgDataBuf == NULL)  
  1892.     {     
  1893.         bRet = FALSE;  
  1894.         goto ERROR_END_FUNCTION;  
  1895.     }  
  1896.   
  1897.     // 拷贝数据  
  1898.     bRet = TRUE;  
  1899.     memcpy(m_pImgDataBuf, bitmapData.Scan0, m_ImageInfo.Width * m_ImageInfo.Height * 4);    
  1900.   
  1901. ERROR_END_FUNCTION:  
  1902.     pBitmapImage->UnlockBits(&bitmapData);    
  1903.     pBitmapImage->Release();       
  1904.     return bRet;  
  1905. }  
  1906.   
  1907. // 销毁图片原始数据  
  1908. void CWFBitmap::DeleteImgDateBuf(void)  
  1909. {  
  1910.     if (m_pImgDataBuf != NULL)  
  1911.     {  
  1912.         delete[] m_pImgDataBuf;  
  1913.         m_pImgDataBuf = NULL;  
  1914.         m_dwcbImgDataBufSize = 0;  
  1915.     }  
  1916. }  
  1917.   
  1918. // 拷贝一个IBitmapImage到另一个IBitmapImage中  
  1919. BOOL CWFBitmap::CopyBitmapImage(  
  1920.     IBitmapImage *pSrcBitmapImage,           // 源IBitmapImage  
  1921.     PWFIBitmapImage &pDstBitmapImage         // 目标IBitmapImage  
  1922.     )  
  1923. {  
  1924.     // 释放目标对象  
  1925.     if (pDstBitmapImage != NULL)  
  1926.     {  
  1927.         pDstBitmapImage->Release();  
  1928.         pDstBitmapImage = NULL;  
  1929.     }  
  1930.   
  1931.     // 参数有效性  
  1932.     if (pSrcBitmapImage == NULL)  
  1933.     {  
  1934.         return FALSE;  
  1935.     }  
  1936.   
  1937.     // 得到原图IImage  
  1938.     IImage *pSrcImage = NULL;  
  1939.     HRESULT hr = pSrcBitmapImage->QueryInterface(IID_IImage, (void**)&pSrcImage);  
  1940.     if (FAILED(hr))  
  1941.     {  
  1942.         printf("CopyBitmapImage QueryInterface SrcImage Error!\n");  
  1943.         return FALSE;  
  1944.     }  
  1945.   
  1946.     // 使用到的临时变量在此处声明,因为下面需要使用goto语句  
  1947.     BOOL bRet = FALSE;                  // 用于返回函数结果  
  1948.     ImageInfo srcImageInfo;             // 存放原图图像信息  
  1949.     RECT rect;                          // 用于锁定图像数据时的区域  
  1950.     BitmapData srcBitmapData;           // 用于锁定原图数据   
  1951.     BOOL bLockedSrcImg = FALSE;         // 是否锁定原图   
  1952.     BitmapData dstBitmapData;           // 用于锁定新图像数据  
  1953.     BOOL bLockedDstImg = FALSE;         // 是否锁定新图  
  1954.   
  1955.     // 得到原图ImageInfo      
  1956.     hr = pSrcImage->GetImageInfo(&srcImageInfo);  
  1957.     if (FAILED(hr))  
  1958.     {  
  1959.         printf("CopyBitmapImage GetImageInfo srcImageInfo Error!\n");         
  1960.         bRet = FALSE;  
  1961.         goto THEEND_FOR_THISFOUNCTION;  
  1962.     }  
  1963.   
  1964.     // 锁定原图数据区  
  1965.     rect.left = 0;  
  1966.     rect.top = 0;  
  1967.     rect.right = srcImageInfo.Width;  
  1968.     rect.bottom = srcImageInfo.Height;  
  1969.     srcBitmapData.Width = srcImageInfo.Width;    
  1970.     srcBitmapData.Height = srcImageInfo.Height;    
  1971.     srcBitmapData.PixelFormat = srcImageInfo.PixelFormat;   
  1972.     hr = pSrcBitmapImage->LockBits(&rect, ImageLockModeRead, srcImageInfo.PixelFormat, &srcBitmapData);  
  1973.     bLockedSrcImg = TRUE;  
  1974.     if (FAILED(hr))  
  1975.     {  
  1976.         printf("CopyBitmapImage LockBits srcBitmapData Error!\n");  
  1977.         bLockedSrcImg = FALSE;  
  1978.         bRet = FALSE;  
  1979.         goto THEEND_FOR_THISFOUNCTION;  
  1980.     }  
  1981.   
  1982.     //  
  1983.     // 创建新的位图  
  1984.     hr = m_pImagingFactory->CreateNewBitmap(srcImageInfo.Width, srcImageInfo.Height, PIXFMT_32BPP_ARGB, &pDstBitmapImage);     
  1985.     if (FAILED(hr))  
  1986.     {  
  1987.         printf("CopyBitmapImage CreateNewBitmap Error!\n");       
  1988.         bRet = FALSE;  
  1989.         goto THEEND_FOR_THISFOUNCTION;  
  1990.     }      
  1991.   
  1992.     // 锁定新位图数据    
  1993.     dstBitmapData.Width = srcImageInfo.Width;    
  1994.     dstBitmapData.Height = srcImageInfo.Height;    
  1995.     dstBitmapData.PixelFormat = srcImageInfo.PixelFormat;     
  1996.     hr = pDstBitmapImage->LockBits(&rect, ImageLockModeRead, PIXFMT_32BPP_ARGB, &dstBitmapData);    
  1997.     bLockedDstImg = TRUE;  
  1998.     if (FAILED(hr))  
  1999.     {  
  2000.         printf("CopyBitmapImage LockBits dstBitmapData Error!\n");  
  2001.         bLockedDstImg = FALSE;  
  2002.         bRet = FALSE;  
  2003.         goto THEEND_FOR_THISFOUNCTION;        
  2004.     }  
  2005.   
  2006.     //  
  2007.     // 把原图数据写人新图          
  2008.     memcpy((BYTE*)dstBitmapData.Scan0, (BYTE*)srcBitmapData.Scan0, srcImageInfo.Width*srcImageInfo.Height*4);     
  2009.     bRet = TRUE;      
  2010.   
  2011.     // 进入资源释放过程  
  2012. THEEND_FOR_THISFOUNCTION:  
  2013.     // 锁定了原图  
  2014.     if (bLockedSrcImg == TRUE)  
  2015.     {  
  2016.         pSrcBitmapImage->UnlockBits(&srcBitmapData);  
  2017.     }  
  2018.   
  2019.     // 锁定了新图  
  2020.     if (bLockedDstImg == TRUE)  
  2021.     {  
  2022.         pDstBitmapImage->UnlockBits(&dstBitmapData);  
  2023.     }  
  2024.   
  2025.     // 释放原图IImage  
  2026.     if (pSrcImage != NULL)  
  2027.     {  
  2028.         pSrcImage->Release();  
  2029.         pSrcImage = NULL;  
  2030.     }  
  2031.   
  2032.     // 返回结果  
  2033.     return bRet;  
  2034. }  


涉及到的矩形类头文件如下:

  1. /******************************************************************** 
  2.     Copyright(c) 2011,  
  3.     All rights reserved. 
  4.     purpose:    矩形类 
  5.  
  6.     当前版本:   1.0 
  7.     作    者:   zhangwf 
  8.     创建日期:   2011:9:6 
  9.     完成日期:    
  10.      
  11.     取代版本: 
  12.     作    者: 
  13.     完成日期:    
  14. *********************************************************************/  
  15. #ifndef _WF_RECT_H_  
  16. #define _WF_RECT_H_  
  17. //  
  18. class CWFRect  
  19. {  
  20. public// 成员变量  
  21.     long x;    // 左上角X坐标  
  22.     long y;    // 左上角Y坐标  
  23.     long w;    // 矩形宽度  
  24.     long h;    // 矩形高度  
  25.   
  26. public:  
  27.     // 构造函数  
  28.     CWFRect();  
  29.   
  30.     // 析构函数  
  31.     ~CWFRect();  
  32.   
  33.     // 带参构造  
  34.     CWFRect(long x, long y, long w, long h);  
  35.   
  36.     // 拷贝构造函数  
  37.     CWFRect(const CWFRect &other);    
  38.   
  39.     // 赋值函数  
  40.     CWFRect& operator=(const CWFRect &other);    
  41.   
  42.     // 比较是否相等  
  43.     bool operator==(const CWFRect &other);  
  44.   
  45.     // 比较是否不等  
  46.     bool operator!=(const CWFRect &other);  
  47.   
  48.     // 检查是否被另一个矩形包含   
  49.     bool operator<=(const CWFRect &other);  
  50.   
  51.     // 检查是否包含另一个矩形    
  52.     bool operator>=(const CWFRect &other);  
  53.   
  54.     // 求矩形交集,没有交集返回CWFRect(0,0,0,0)  
  55.     CWFRect operator&(const CWFRect &other);  
  56.   
  57.     // 求矩形交集,没有交集结果为CWFRect(0,0,0,0)  
  58.     CWFRect& operator&=(const CWFRect &other);  
  59.   
  60.     // 求并集,返回能够包含此两个矩形的矩形区域  
  61.     CWFRect operator|(const CWFRect &other);  
  62.   
  63.     // 求并集,结果为能够包含此两个矩形的矩形区域  
  64.     CWFRect& operator|=(const CWFRect &other);  
  65.   
  66.     // 该矩形区域是否包含某点  
  67.     bool CheckIn(long x, long y);  
  68.   
  69.     // 检测是否有效(检测矩形宽度和高度不能小于或等于0)  
  70.     bool CheckValid(void);  
  71. };  
  72.   
  73. //  
  74. #endif  


 

涉及到的矩形类实现文件如下:

  1. /******************************************************************** 
  2.     Copyright(c) 2011,  
  3.     All rights reserved. 
  4.     purpose:    矩形类 
  5.  
  6.     当前版本:   1.0 
  7.     作    者:   zhangwf 
  8.     创建日期:   2011:9:6 
  9.     完成日期:    
  10.      
  11.     取代版本: 
  12.     作    者: 
  13.     完成日期:    
  14. *********************************************************************/  
  15. #include "WFRect.h"  
  16. //  
  17. // 构造函数  
  18. CWFRect::CWFRect()  
  19. : x(0)  
  20. , y(0)  
  21. , w(0)  
  22. , h(0)  
  23. {  
  24.   
  25. }  
  26.   
  27. // 析构函数  
  28. CWFRect::~CWFRect()  
  29. {  
  30.   
  31. }  
  32.   
  33. // 带参构造  
  34. CWFRect::CWFRect(long x, long y, long w, long h)  
  35. : x(x)  
  36. , y(y)  
  37. , w(w)  
  38. , h(h)  
  39. {  
  40.   
  41. }  
  42.   
  43. // 拷贝构造函数  
  44. CWFRect::CWFRect(const CWFRect &other)  
  45. : x(other.x)  
  46. , y(other.y)  
  47. , w(other.w)  
  48. , h(other.h)  
  49. {  
  50.   
  51. }  
  52.   
  53. // 赋值函数  
  54. CWFRect& CWFRect::operator=(const CWFRect &other)  
  55. {  
  56.     // 检查自赋值  
  57.     if (this == &other)  
  58.     {  
  59.         return *this;  
  60.     }  
  61.   
  62.     // 赋值  
  63.     x = other.x;  
  64.     y = other.y;  
  65.     w = other.w;  
  66.     h = other.h;  
  67.     return *this;  
  68. }  
  69.   
  70. // 比较是否相等  
  71. bool CWFRect::operator==(const CWFRect &other)  
  72. {  
  73.     // 检查是否和自己比较  
  74.     if (this == &other)  
  75.     {  
  76.         return true;  
  77.     }  
  78.   
  79.     // 比较是否相等  
  80.     return (x==other.x && y==other.y && w==other.w && h==other.h);  
  81. }  
  82.   
  83. // 比较是否不等  
  84. bool CWFRect::operator!=(const CWFRect &other)  
  85. {  
  86.     // 检查是否和自己比较  
  87.     if (this == &other)  
  88.     {  
  89.         return false;  
  90.     }  
  91.   
  92.     // 比较是否不等  
  93.     return (x!=other.x || y!=other.y || w!=other.w || h!=other.h);  
  94. }  
  95.   
  96. // 检查是否被另一个矩形包含   
  97. bool CWFRect::operator<=(const CWFRect &other)  
  98. {  
  99.     // 检查是否和自己比较  
  100.     if (this == &other)  
  101.     {  
  102.         return true;  
  103.     }  
  104.   
  105.     // 比较是否被另一个矩形包含  
  106.     return (x>=other.x && (x+w)<=(other.x+other.w) && y>=other.y && (y+h)<=(other.y+other.h));  
  107. }  
  108.   
  109. // 检查是否包含另一个矩形    
  110. bool CWFRect::operator>=(const CWFRect &other)  
  111. {  
  112.     // 检查是否和自己比较  
  113.     if (this == &other)  
  114.     {  
  115.         return true;  
  116.     }  
  117.   
  118.     // 比较是否包含另一个矩形  
  119.     return (other.x>=x && (other.x+other.w)<=(x+w) && other.y>=y && (other.y+other.h)<=(y+h));  
  120. }  
  121.   
  122. // 求矩形交集  
  123. CWFRect CWFRect::operator&(const CWFRect &other)  
  124. {  
  125.     // 是否和自己求交集  
  126.     if (this == &other)  
  127.     {  
  128.         return *this;  
  129.     }  
  130.   
  131.     // 计算相交区域左上角点坐标  
  132.     long lTopX = (x >= other.x) ? x : other.x;  
  133.     long lTopY = (y >= other.y) ? y : other.y;  
  134.   
  135.     // 计算相交区域有效角点坐标  
  136.     long rBtmX = ((x+w) >= (other.x+other.w)) ? (other.x+other.w) : (x+w);  
  137.     long rBtmY = ((y+h) >= (other.y+other.h)) ? (other.y+other.h) : (y+h);  
  138.   
  139.     // 返回交集  
  140.     return (lTopX>rBtmX || lTopY>rBtmY) ? CWFRect(0,0,0,0) : CWFRect(lTopX, lTopY, rBtmX-lTopX, rBtmY-lTopY);  
  141. }  
  142.   
  143. // 求矩形交集  
  144. CWFRect& CWFRect::operator&=(const CWFRect &other)  
  145. {  
  146.     // 是否和自己求交集  
  147.     if (this == &other)  
  148.     {  
  149.         return *this;  
  150.     }  
  151.   
  152.     // 计算相交区域左上角点坐标  
  153.     long lTopX = (x >= other.x) ? x : other.x;  
  154.     long lTopY = (y >= other.y) ? y : other.y;  
  155.   
  156.     // 计算相交区域有效角点坐标  
  157.     long rBtmX = ((x+w) >= (other.x+other.w)) ? (other.x+other.w) : (x+w);  
  158.     long rBtmY = ((y+h) >= (other.y+other.h)) ? (other.y+other.h) : (y+h);  
  159.   
  160.     // 计算交集结果  
  161.     // 没有交集  
  162.     if (lTopX>rBtmX || lTopY>rBtmY)  
  163.     {  
  164.         x = 0;  
  165.         y = 0;  
  166.         w = 0;  
  167.         h = 0;  
  168.     }  
  169.     // 具有交集  
  170.     else  
  171.     {  
  172.         x = lTopX;  
  173.         y = lTopY;  
  174.         w = rBtmX - lTopX;  
  175.         h = rBtmY - lTopY;    
  176.     }  
  177.   
  178.     // 返回结果  
  179.     return *this;  
  180. }  
  181.   
  182. // 求并集,返回能够包含此两个矩形的矩形区域  
  183. CWFRect CWFRect::operator|(const CWFRect &other)  
  184. {  
  185.     // 是否和自己求并集  
  186.     if (this == &other)  
  187.     {  
  188.         return *this;  
  189.     }  
  190.   
  191.     // 计算合并区域左上角坐标  
  192.     long lTopX = (x <= other.x) ? x : other.x;  
  193.     long lTopY = (y <= other.y) ? y : other.y;  
  194.   
  195.     // 计算合并区域右下角坐标  
  196.     long rBtmX = ((x+w) <= (other.x+other.w)) ? (other.x+other.w) : (x+w);  
  197.     long rBtmY = ((y+h) <= (other.y+other.h)) ? (other.y+other.h) : (y+h);  
  198.   
  199.     // 返回并集  
  200.     return CWFRect(lTopX, lTopY, rBtmX-lTopX, rBtmY-lTopY);  
  201. }  
  202.   
  203. // 求并集,结果为能够包含此两个矩形的矩形区域  
  204. CWFRect& CWFRect::operator|=(const CWFRect &other)  
  205. {  
  206.     // 是否和自己求并集  
  207.     if (this == &other)  
  208.     {  
  209.         return *this;  
  210.     }  
  211.   
  212.     // 计算合并区域左上角坐标  
  213.     long lTopX = (x <= other.x) ? x : other.x;  
  214.     long lTopY = (y <= other.y) ? y : other.y;  
  215.   
  216.     // 计算合并区域右下角坐标  
  217.     long rBtmX = ((x+w) <= (other.x+other.w)) ? (other.x+other.w) : (x+w);  
  218.     long rBtmY = ((y+h) <= (other.y+other.h)) ? (other.y+other.h) : (y+h);  
  219.   
  220.     // 计算并集  
  221.     x = lTopX;  
  222.     y = lTopY;  
  223.     w = rBtmX - lTopX;  
  224.     h = rBtmY - lTopY;  
  225.     return *this;  
  226. }  
  227.   
  228. // 该矩形区域是否包含某点  
  229. bool CWFRect::CheckIn(long x, long y)  
  230. {  
  231.     return (x>=this->x && x<=(this->x+this->w) && y>=this->y && y<=(this->y+this->h));  
  232. }  
  233.   
  234. // 检测是否有效(检测矩形宽度和高度不能小于或等于0)  
  235. bool CWFRect::CheckValid(void)  
  236. {  
  237.     return (w>0 && h>0);  



转载自:http://blog.csdn.net/werocpp/article/details/7435784

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值