IImageEx

本文介绍了一个基于Windows CE的图片处理类IImageEx,该类实现了从文件加载图片到位图、从资源加载图片缓冲区以及绘制图片等功能。通过COM接口与Imaging对象交互,提供了丰富的图像操作。

#pragma once
/********************************************************************
 file name :  g:/工具源码/WinCE/CE600WinCode/COMImage.h
 author  : Clark
 created  : 27:1:2011   16:09
 purpose  : 实现IImage操作
*********************************************************************/
#include <Imaging.h>


class IImageEx
{
public:
 static BOOL Init();
 static void UnInit();
 static HBITMAP LoadImageFromFile(TCHAR * pFileImage);

public:
 explicit IImageEx();
 ~IImageEx();
 BOOL LoadBuf(HINSTANCE hResource, UINT ResID, TCHAR* lpType);
 void loadFile(LPCWSTR lpResourceName);
 void drawImage(HDC* pDC, RECT rtDest, RECT rtSrc);

 static IImagingFactory  *g_pIImgFactory;
 IImage* m_pIImage;
};

 

 

////////////////////////////////////////////////////////////////////////

 

 

#include "stdafx.h"
#include <INITGUID.h>
#include "COMImage.h"
#include <AFX.h>
#include <string.h>

#pragma comment (lib,"Ole32.lib")

 

IImagingFactory* IImageEx::g_pIImgFactory = NULL;

BOOL IImageEx::Init()
{
 CoInitializeEx(NULL,COINIT_MULTITHREADED);
 HRESULT hResult = CoCreateInstance(CLSID_ImagingFactory,NULL,
  CLSCTX_INPROC_SERVER,
  IID_IImagingFactory,
  (void **)&g_pIImgFactory);
 return (hResult == S_OK);
}

void IImageEx::UnInit()
{
 if(g_pIImgFactory)
 {
  g_pIImgFactory->Release();
  g_pIImgFactory = NULL;
 }
 CoUninitialize();
}

IImageEx::IImageEx():m_pIImage(NULL){}
IImageEx::~IImageEx()
{
 if( NULL != m_pIImage)
 {
  m_pIImage->Release();
  delete m_pIImage;
 }
 m_pIImage = NULL;
}

HBITMAP IImageEx::LoadImageFromFile(TCHAR * pFileImage)
{
 HBITMAP hResult = 0;
 IImage *pImageBmp = NULL;
 ImageInfo imageInfo;
 HRESULT hr = g_pIImgFactory->CreateImageFromFile(pFileImage, &pImageBmp);
 if (SUCCEEDED(hr)&& SUCCEEDED(pImageBmp->GetImageInfo(&imageInfo)))
 {
  CWindowDC dc(0);
  CDC dcBitmap;
  dcBitmap.CreateCompatibleDC(&dc);
  hResult = CreateCompatibleBitmap(dc.GetSafeHdc(),imageInfo.Width, imageInfo.Height);
  HGDIOBJ hOldBitmap = SelectObject(dcBitmap, hResult);
  //note:内存不足的话,Draw操作可能会失败
  pImageBmp->Draw(dcBitmap, CRect(0, 0, imageInfo.Width, imageInfo.Height), NULL);
  SelectObject(dcBitmap, hOldBitmap);
  DeleteDC(dcBitmap);
  pImageBmp->Release();
 }
 return hResult;
}

void IImageEx::loadFile(LPCWSTR lpResourceName)
{
 HRSRC hrRes;
 HRESULT hr;
 HGLOBAL hGlobal;
 LPSTR lpRes;
 DWORD dwSize;
 HMODULE hModule_Current;
 hModule_Current = GetModuleHandle (NULL); //获得文件句柄
 hrRes = FindResource (hModule_Current, lpResourceName, RT_RCDATA); //查找资源
 dwSize = SizeofResource (GetModuleHandle (NULL), hrRes); //获得资源文件大小
 hGlobal = LoadResource (GetModuleHandle (NULL), hrRes); //加载文件
 lpRes = (LPSTR)LockResource (hGlobal); //锁定资源文件
 if (!SUCCEEDED (hr=g_pIImgFactory->CreateImageFromFile (lpResourceName, &m_pIImage))) //从文件中创建对象
 {
  TRACE(_T("Failed to COM_IMAGE!"));
  AfxMessageBox(lpResourceName);
  DeleteObject(hrRes);
  exit(0);
 }
 DeleteObject(hrRes);
}

BOOL IImageEx::LoadBuf(HINSTANCE hResource, UINT ResID, TCHAR* lpType)
{
 if(NULL == g_pIImgFactory)
  return FALSE;

 if(!hResource)
  return FALSE;
 HRSRC  hRes = FindResource(hResource , MAKEINTRESOURCE(ResID) , lpType);
 if(!hRes)
 {
  return FALSE;
 }
 HGLOBAL  hGlobal = LoadResource(hResource , hRes);
 if(!hGlobal)
 {
  return FALSE;
 }
 LPVOID  pData = LockResource( hGlobal );
 DWORD  dwSize = SizeofResource(hResource , hRes);
 g_pIImgFactory->CreateImageFromBuffer(pData , dwSize ,  BufferDisposalFlagNone , &m_pIImage);
 FreeResource(hGlobal);
 pData = NULL;
 return true;
}

void IImageEx::drawImage(HDC* pDC, RECT rtDest, RECT rtSrc)
{
 ImageInfo imfo;
 m_pIImage->GetImageInfo(&imfo);
 double dDotPermmX = imfo.Xdpi / 25.4;
 double dDotPermmY = imfo.Ydpi / 25.4;
 //pSrcRect指向以像素点为单位的区域
 RECT rcSrc =
 {
  (LONG)(rtSrc.left / dDotPermmX / 0.01),
  (LONG)(rtSrc.top / dDotPermmY / 0.01),
  (LONG)(rtSrc.right / dDotPermmX / 0.01),
  (LONG)(rtSrc.bottom / dDotPermmY / 0.01)
 };
 m_pIImage->Draw(*pDC, &rtDest, &rcSrc);
}

使用GDI+库显示gif动态图片,该类接口如下: 可以看出,该ImageEx完全继承了基类的接口函数。 说明: 如果打开非多帧图片,该类几乎完全等价于基类,比如你可以把该类的对象代入Graphics类系列的成员函数中; 如果打开的是多帧的图片,你只要打开图片后不调用InitAnimation函数(它会创建线程),则上述做法依然可以; 但如果调用InitAnimation函数后(单帧图像没关系,因为不会创建线程),则不可以了, 所有的基类继承过来的接口成员函数和配合gdi+库其他类的函数调用都是不可以的,因为没有作线程同步, 你只能调用下面位数不多的几个public成员函数,调用Destroy成员函数后,则就可以了,因为它会关闭线程。 其实你会发现下面的public成员函数操作的成员变量都是新增的成员变量,没涉及到线程同步问题。 class ImageEx : public Image { public: //以长度为nSize的内存pBuff中的内容构造图像 ImageEx(const void* pBuff, size_t nSize, BOOL useEmbeddedColorManagement = FALSE); //以类型为sResourceType,名称为sResource的资源构造图像 ImageEx(LPCTSTR sResourceType, LPCTSTR sResource, BOOL useEmbeddedColorManagement = FALSE); //以文件构造图像 ImageEx(LPCTSTR filename, BOOL useEmbeddedColorManagement = FALSE); //调用Destroy成员函数 ~ImageEx(); public: //如果已经构造的对象是动画,则创建动画线程,并返回true, //如果为静态图像或已经创建过动画线程,则也返回false // 图像将绘制在m_hWnd客户区的rect区域,会拉伸,支持镜像 bool InitAnimation(HWND hWnd, RECT rect); //判断是否为动画 bool IsAnimatedGIF() { return m_nFrameCount > 1; } //设置动画暂停与否 void SetPause(bool bPause); //判断动画是否处于暂停状态 bool IsPaused() { return m_bPause; } //关闭动画,事实上基类Image中还有的两个成员变量没有关闭,因为析构函数会调用基类析构函数进行关闭的 void Destroy(); //另外的非public的东西省略.. }; 用法: MFC对话框程序在下面添加: BOOL CTestDlgDlg::OnInitDialog() { CDialog::OnInitDialog(); //其它的初始化代码 // GDI+ //m_imageImageEx指针类型成员变量,"GIF"为资源类型,"HEARTS"为资源名称 m_image = new ImageEx( _T("GIF"), _T("HEARTS") ); RECT rc; GetClientRect(&rc); m_image->InitAnimation(this->m_hWnd, rc);//创建gif播放线程 return TRUE; // return TRUE unless you set the focus to a control } CTestDlgDlg::~CTestDlgDlg() { // GDI+ delete m_image; } 其中的m_image = new ImageEx( _T("GIF"), _T("HEARTS") );你可以换成ImageEx类的另外两个构造函数
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
红包 添加红包
表情包 插入表情
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值