VC++ 图片资源管理器

头文件声明(CImageFactory.h):

#pragma once
#include "SingleInstanceBase.h"

#include <map>
#include <string>
using namespace std;

#include <GdiPlus.h>
using namespace Gdiplus;

typedef struct tagImgResource
{
	Bitmap* pImage;
	BYTE* lpResrc;
	HGLOBAL hMem;
	IStream* pStream;
	void FreeAndNil()
	{
		GlobalUnlock(hMem);
		GlobalFree(hMem);
		pStream->Release();
		delete pImage;
		pImage = NULL;
		delete this;
	}
}ImgResource, *PImgResource;
class CImageFactory: public SingleInstanceBase<CImageFactory>
{
public:
	CImageFactory(void);
	~CImageFactory(void);

public:
	// 设置图片加载路径
	void	SetSkinLoadPath(LPCTSTR lpszSkinLoadPath);
	// 设置ZIP图片包文件名称
	void	SetSkinZipPacketName(LPCTSTR lpszSkinZipPacketName);

	// 从本地磁盘加载
	Gdiplus::Image*	GetSkinItemImage(LPCTSTR lpszFileName);
	// 从资源文件加载
	Gdiplus::Image*	GetSkinItemImage(UINT ID, LPCTSTR lpszType);
	
private:
	// 从zip压缩包加载
	Gdiplus::Image*	GetSkinItemImage(LPCTSTR lpszZipPackFileName, LPCTSTR lpszFileName);

private:
	// 资源名称,图片数据
	std::map<std::string, Image*>  m_mapSkinItems;
	// 资源ID,图片数据
	std::map<UINT, ImgResource*>  m_mapSkinResItems;

	// 本地加载路径
	std::string m_strSkinLoadPath;
	// zip压缩包文件名称
	std::string m_strSkinZipPacketName;

	ULONG_PTR gdiplusToken;

private:
	// 解压zip文件,默认路径AppData
	BOOL UnZipPacket(LPCTSTR lpszZipPackFileName);
};

源码实现(CImageFactory.cpp):

#include "StdAfx.h"
#include "CImageFactory.h"
#include "./zip/ZipImplement.h"

#include <shlwapi.h>
#pragma comment(lib, "Shlwapi.lib")

_MACRO_SINGLETON_(CImageFactory)
CImageFactory::CImageFactory(void)
{
	::GdiplusStartupInput gdiplusStartupInput;
	::GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL);

	TCHAR szFilePath[MAX_PATH + 1];
	::GetModuleFileName(NULL, szFilePath, MAX_PATH);
	(_tcsrchr(szFilePath, _T('\\')))[1] = 0;
	m_strSkinLoadPath = szFilePath;
}


CImageFactory::~CImageFactory(void)
{
	{
		std::map<std::string, Image*>::iterator iter;
		for (iter = m_mapSkinItems.begin();iter != m_mapSkinItems.end();iter++)
		{
//             if (iter->second!=NULL && iter->second->GetLastStatus() ==Ok )
//             {
//                 delete iter->second;
//                 iter->second = NULL;
//             }

			delete iter->second;
		}
	}

	{
		std::map<UINT, ImgResource*>::iterator iter;
		for (iter = m_mapSkinResItems.begin();iter != m_mapSkinResItems.end();iter++)
		{
			ImgResource* pImgResource = iter->second;
			::GlobalUnlock(pImgResource->hMem);
			::GlobalFree(pImgResource->hMem);
			pImgResource->pStream->Release();
			::FreeResource(pImgResource->lpResrc);
		}
	}

	::GdiplusShutdown(gdiplusToken);
}

void  CImageFactory::SetSkinLoadPath(LPCTSTR lpszSkinLoadPath)
{
	m_strSkinLoadPath = lpszSkinLoadPath;
}

void CImageFactory::SetSkinZipPacketName(LPCTSTR lpszSkinZipPacketName)
{
	m_strSkinZipPacketName = lpszSkinZipPacketName;
}

Image* CImageFactory::GetSkinItemImage(LPCTSTR lpszFileName)
{
	// 先从本地资源表匹配,然后从硬盘获取,最后从压缩包文件获取
	Image* pImage = NULL;
	if (NULL != pImage)
		return pImage;

	std::map<std::string,Image*>::iterator iter;
	iter = m_mapSkinItems.find(lpszFileName);
	if (iter == m_mapSkinItems.end())
	{
		std::string strImgPath = m_strSkinLoadPath + lpszFileName;
		if ( ::PathFileExists(strImgPath.c_str()) )
		{
			std::wstring wsImgPath = CStringHelper::Ansi2Unicode(strImgPath.c_str());
			pImage = (Image*)Bitmap::FromFile(wsImgPath.c_str());
			if (pImage && pImage->GetLastStatus() == Ok)
				m_mapSkinItems[lpszFileName] = pImage;
			//pImage->RotateFlip(RotateFlipType::Rotate90FlipX);
		}
	}
	else
	{
		pImage = iter->second;
	}

	if (pImage == NULL || pImage->GetLastStatus() != Ok)
	{
		pImage = GetSkinItemImage(m_strSkinZipPacketName.c_str(), lpszFileName);
	}

	return pImage;
}

BOOL CImageFactory::UnZipPacket(LPCTSTR lpszZipPackFileName)
{
	CZipImplement ZipImplement;
	sw::string sUnPackPath;
	TCHAR szPathName[MAX_PATH + 1] = { 0 };
	::GetModuleFileName(NULL, szPathName, sizeof(szPathName));
	TCHAR szDrive[_MAX_DRIVE] = {0};
	TCHAR szDir[_MAX_DIR] = {0};
	TCHAR szFilename[_MAX_FNAME] = {0};
	TCHAR szExt[_MAX_EXT] = {0};
	_splitpath_s(&szPathName[0], szDrive, szDir, szFilename, szExt);
	sUnPackPath.Format("%s", GetLocalAppDataPath(szFilename).c_str());
	return ZipImplement.Zip_UnPackFiles(lpszZipPackFileName, sUnPackPath.c_str());
}

Image*	CImageFactory::GetSkinItemImage(UINT ID, LPCTSTR lpszType)
{
	ImgResource* pImgResource = NULL;
	std::map<UINT, ImgResource*>::iterator iter;
	iter = m_mapSkinResItems.find(ID);
	if (iter == m_mapSkinResItems.end())
	{
		HINSTANCE hInst = AfxGetResourceHandle();
		HRSRC hResrc = ::FindResource(hInst, MAKEINTRESOURCE(ID), lpszType);
		if (hResrc == NULL)
			return NULL;

		DWORD len = SizeofResource(hInst, hResrc);
		BYTE* lpResrc = (BYTE*)LoadResource(hInst, hResrc);
		if (lpResrc == NULL)
			return NULL;

		pImgResource = new ImgResource();
		pImgResource->lpResrc = lpResrc;
		pImgResource->hMem = GlobalAlloc(GMEM_FIXED, len);
		BYTE* pMem = (BYTE*)GlobalLock(pImgResource->hMem);
		memcpy(pMem, lpResrc, len);
		CreateStreamOnHGlobal(pImgResource->hMem, FALSE, &pImgResource->pStream);
		pImgResource->pImage = (Gdiplus::Bitmap*)Bitmap::FromStream(pImgResource->pStream);
		m_mapSkinResItems[ID] = pImgResource;
	}
	else
	{
		pImgResource = iter->second;
	}

	return pImgResource->pImage;
}

Gdiplus::Image* CImageFactory::GetSkinItemImage(LPCTSTR lpszZipPackFileName, LPCTSTR lpszFileName)
{
	Image* pImage = NULL;
	std::map<std::string,Image*>::iterator iter;
	iter = m_mapSkinItems.find(lpszFileName);
	if (iter == m_mapSkinItems.end())
	{
		CZipImplement ZipImplement;
		CString lpszUnPackPath;
		TCHAR szPathName[MAX_PATH + 1] = { 0 };
		::GetModuleFileName(NULL, szPathName, sizeof(szPathName));
		TCHAR szDrive[_MAX_DRIVE] = {0};
		TCHAR szDir[_MAX_DIR] = {0};
		TCHAR szFilename[_MAX_FNAME] = {0};
		TCHAR szExt[_MAX_EXT] = {0};
		_splitpath_s(&szPathName[0], szDrive, szDir, szFilename, szExt);
		lpszUnPackPath.Format("%s", GetLocalAppDataPath(szFilename).c_str());

		char* buffer = NULL;
		int iSize = 0;
		if ( ZipImplement.Zip_GetPackData(lpszZipPackFileName, lpszFileName, &buffer, iSize) ) 
		{
			IStream *stream = NULL;
			HGLOBAL global = ::GlobalAlloc( GMEM_MOVEABLE, iSize );
			if( global == NULL )
			{
				delete[] buffer;
				buffer = NULL;
				return NULL;
			}
			void *dest = ::GlobalLock( global );
			if( dest == NULL )
			{
				delete[] buffer;
				buffer = NULL;
				return NULL;
			}

			memcpy( dest, buffer, iSize );
			::GlobalUnlock( global );

			if( ::CreateStreamOnHGlobal( global, TRUE, &stream ) != S_OK )
			{
				::GlobalFree( global );
				delete[] buffer;
				buffer = NULL;
				return NULL;
			}

			Gdiplus::Bitmap *image = Gdiplus::Bitmap::FromStream( stream );
			stream->Release();
			delete[] buffer;
			buffer = NULL;
			return image;
		}

		delete[] buffer;
		buffer = NULL;
		return NULL;
	}
	else
	{
		pImage = iter->second;
		return pImage;
	}
}

 

  • 0
    点赞
  • 2
    收藏
    觉得还不错? 一键收藏
  • 2
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论 2
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值