WINCE实现图片加载绘制类,支持ALPHA运算绘制PNG透明图片

封装WINCE下加载和绘制图片类,支持PNG透明

头文件:

/******************************************************************** Copyright(c) 2010, All rights reserved. created: 28:6:2010 16:02 filename: f:/个人资料_zwf/MyCodeNewModify/BnvOSBaseClass/BnvOSBaseClass/BnvOSBaseClassInclude/CBnvImage.h file ext: h author: zhangwf purpose: 封装加载图片类,在写WIN32程序时加载图片绘制图片方便使用; 目前只支持简单的加载和显示,支持重复加载,但是不要使用 相互赋值及其他操作,可能会出现问题; 当前版本: 1.0 作 者: zwf 完成日期: 取代版本: 作 者: 完成日期: *********************************************************************/ #ifndef _CBNV_IMAGE_H_ #define _CBNV_IMAGE_H_ ////////////////////////////////////////////////////////////////////////// #include <Windows.h> #include <imaging.h> ////////////////////////////////////////////////////////////////////////// class CBnvImage { public: CBnvImage(); ~CBnvImage(); public: // 接口函数 // 从文件中加载 BOOL LoadFromFile(const TCHAR *fileName); // 从资源中加载,例如g_backImg.LoadFromResource(MAKEINTRESOURCE(IDR_BACKIMG), _T("PNG")); BOOL LoadFromResource(LPCWSTR lpName, LPCWSTR lpType); // 释放已经加载到的资源 void ReleaseResource(void); // 绘制图像到指定位置,绘制整个图像,会把图像压缩或拉伸填充到指定区域 void Draw(HDC hdc, const RECT* dstRect); // 绘制图像上一部分到指定的部分(先绘制到内存DC,再绘制到目标DC) void Draw(HDC hdc, const RECT* dstRect, const RECT* srcRect); // 绘制图像上一部分到指定的区域(支持alpha混合) void DrawAlpha(HDC hdc, const RECT* dstRect, const RECT* srcRect); // 获得图像的宽度 int GetWidth(); // 获得图像的高度 int GetHeight(); private: // 成员变量 ImageInfo m_ImageInfo; IImage *m_pImage; IImagingFactory *m_pImagingFactory; BOOL m_blFlag; // 标识初始化是否成功 HDC m_hDrawDC; // 临时保存DC HBITMAP m_hBitmap; // 临时保存图片 HBITMAP m_hOldBitmap; // 保存原始图像数据(带有alpha通道数据) unsigned char *m_pImgDataBuf; private: // 私有成员函数 // 为图片创建内存DC,及清除内存DC HDC CreatImgDC(HDC hdc); void DelImgDC(); // 取得图片原始数据,及销毁图片原始数据 BOOL GetImgDateBuf(); void DelImgDateBuf(void); }; ////////////////////////////////////////////////////////////////////////// #endif

 

实现源文件如下:

/******************************************************************** Copyright(c) 2010, All rights reserved. created: 28:6:2010 16:03 filename: f:/个人资料_zwf/MyCodeNewModify/BnvOSBaseClass/BnvOSBaseClass/BnvOSBaseClassSource/CBnvImage.cpp file ext: cpp author: zhangwf purpose: 封装加载图片类,在写WIN32程序时加载图片绘制图片方便使用 当前版本: 1.0 作 者: zwf 完成日期: 取代版本: 作 者: 完成日期: *********************************************************************/ ////////////////////////////////////////////////////////////////////////// #include <ObjBase.h> #include <initguid.h> #include "CBnvImage.h" ////////////////////////////////////////////////////////////////////////// // 构造函数 CBnvImage::CBnvImage() { // 初始化变量 m_blFlag = TRUE; m_pImagingFactory = NULL; m_pImage = NULL; m_hDrawDC = NULL; m_hBitmap = NULL; m_hOldBitmap = NULL; m_pImgDataBuf = NULL; // COM初始化 HRESULT hr = NULL; if (FAILED(hr = ::CoInitializeEx(NULL, COINIT_MULTITHREADED))) { m_blFlag = FALSE; } // 创建COM实例 if(FAILED(hr = ::CoCreateInstance(CLSID_ImagingFactory,NULL,CLSCTX_INPROC_SERVER,IID_IImagingFactory,(void**) &m_pImagingFactory))) { m_blFlag = FALSE; } } // 析构函数 CBnvImage::~CBnvImage() { // 销毁内存DC DelImgDC(); // 释放原始数据空间 DelImgDateBuf(); // 释放IMAGE组件相关 if(m_pImage != NULL) { m_pImage->Release(); m_pImage = NULL; } if(m_pImagingFactory != NULL) { m_pImagingFactory->Release(); m_pImagingFactory = NULL; } // 释放COM ::CoUninitialize(); } /******************************************************************** 函数名:LoadFromFile 作者:zhangwf 日期:2009/07/23 功能:从文件中加载图像 参数:fileName 待加载文件名称 返回:类型(BOOL) TRUE-加载成功;FALSE-加载失败; 修改记录: *********************************************************************/ BOOL CBnvImage::LoadFromFile(const TCHAR *fileName) { // 初始化失败 if (m_blFlag == FALSE) { return FALSE; } // 参数有效性 if (fileName == NULL) { return FALSE; } // 释放资源 ReleaseResource(); // 从文件中创建图片 HRESULT hr = NULL; if(FAILED(hr = m_pImagingFactory->CreateImageFromFile(fileName, &m_pImage))) { return FALSE; } // 得到图片信息 if(FAILED(hr = m_pImage->GetImageInfo(&m_ImageInfo))) { return FALSE; } // 成功获得图片信息 return TRUE; } /******************************************************************** 函数名:LoadFromResource 作者:zhangwf 日期:2009/07/24 功能:从资源中加载图片数据 参数:lpName 资源ID lpType 资源类型 返回:类型(BOOL) TRUE-加载成功;FALSE-加载失败; 修改记录: *********************************************************************/ BOOL CBnvImage::LoadFromResource(LPCWSTR lpName, LPCWSTR lpType) { // 初始化失败 if (m_blFlag == FALSE) { return FALSE; } // 释放资源 ReleaseResource(); // 在资源中寻找 HRSRC hr; DWORD dwsize; HGLOBAL hg; LPSTR lp; HMODULE hModule_Current = GetModuleHandle(NULL); hr = FindResource(hModule_Current, lpName, lpType); dwsize = SizeofResource(GetModuleHandle(NULL), hr); hg = ::LoadResource(GetModuleHandle(NULL), hr); 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; } /******************************************************************** 函数名:ReleaseResource 作者:zhangwf 日期:2009/09/09 功能:释放已经加载到的资源,用于释放大的图片暂用的内存 参数: 返回:类型(void) 修改记录: *********************************************************************/ void CBnvImage::ReleaseResource(void) { // 释放DC DelImgDC(); // 释放原始数据空间 DelImgDateBuf(); // 释放IMAGE if(m_pImage != NULL) { m_pImage->Release(); m_pImage = NULL; } } /******************************************************************** 函数名:Draw 作者:zhangwf 日期:2009/07/23 功能:绘制图像到指定的矩形区域,会压缩图像适合指定区域 参数:hdc 绘图环境 dstRect hdc上的目标绘图矩形区域 返回:类型() 修改记录: *********************************************************************/ void CBnvImage::Draw(HDC hdc, const RECT* dstRect) { // 获取图像信息失败 if (m_pImage==NULL || dstRect==NULL) { return; } // 绘制图像 m_pImage->Draw(hdc, dstRect, NULL); } /******************************************************************** 函数名:GetWidth 作者:zhangwf 日期:2009/07/24 功能:获得图像宽度 参数: 返回:类型(int) 图像的宽度 修改记录: *********************************************************************/ int CBnvImage::GetWidth() { return m_ImageInfo.Width; } /******************************************************************** 函数名:GetHeight 作者:zhangwf 日期:2009/07/24 功能:获得图像的高度 参数: 返回:类型(int) 图像的高度 修改记录: *********************************************************************/ int CBnvImage::GetHeight() { return m_ImageInfo.Height; } /******************************************************************** 函数名:Draw 作者:zhangwf 日期:2009/09/16 功能:绘制图像上一部分到指定的部分 参数:hdc 绘图环境 dstRect hdc上的目标绘图矩形区域 srcRect 图像上指定的要绘制出的矩形区域 返回:类型(void) 修改记录: *********************************************************************/ void CBnvImage::Draw(HDC hdc, const RECT* dstRect, const RECT* srcRect) { // 获取图像信息失败 if (m_pImage == NULL) { return; } // 目标绘图区为NULL if (dstRect == NULL) { return; } // 创建内存DC if (m_hDrawDC == NULL) { m_hDrawDC = CreatImgDC(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 ); } } /******************************************************************** 函数名:DrawAlpha 作者:zhangwf 日期:2011/04/28 功能:绘制图像上一部分到指定的部分(支持alpha混合) 参数:hdc 绘图环境 dstRect hdc上的目标绘图矩形区域 srcRect 图像上指定的要绘制出的矩形区域 返回:类型(void) 修改记录: *********************************************************************/ void CBnvImage::DrawAlpha(HDC hdc, const RECT* dstRect, const RECT* srcRect) { // 获取图像信息失败,目标绘图区为NULL if (m_pImage==NULL || dstRect==NULL) { return; } // 获取原始数据失败 if (GetImgDateBuf() == 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 = GetWidth(); rcImgSrc.bottom = GetHeight(); } // 计算实际使用区域的宽度和高度 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*GetWidth() + 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); } // 绘制到临时DC上 HDC CBnvImage::CreatImgDC(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 CBnvImage::DelImgDC() { 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 CBnvImage::GetImgDateBuf() { // 用于返回结果 BOOL bRet = TRUE; // 已经获取到了原始数据 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; m_pImagingFactory->CreateBitmapFromImage(m_pImage, m_ImageInfo.Width, m_ImageInfo.Height, PIXFMT_32BPP_ARGB, InterpolationHintDefault, &pBitmapImage); pBitmapImage->LockBits(&rect, ImageLockModeRead, PIXFMT_32BPP_ARGB, &bitmapData); // 释放旧数据 if (m_pImgDataBuf != NULL) { delete[] m_pImgDataBuf; m_pImgDataBuf = NULL; } // 申请新空间 bRet = TRUE; m_pImgDataBuf = new unsigned char[m_ImageInfo.Width * m_ImageInfo.Height * 4]; 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 CBnvImage::DelImgDateBuf(void) { if (m_pImgDataBuf != NULL) { delete[] m_pImgDataBuf; m_pImgDataBuf = NULL; } }

你可能感兴趣的:(image,function,null,delete,WinCE,colors)