Magic_Game/core/Common/Image.cpp

321 lines
5.6 KiB
C++
Raw Normal View History

2018-05-14 00:36:01 +08:00
#include "..\e2dcommon.h"
#include "..\e2dbase.h"
2018-05-24 15:47:38 +08:00
#include "..\e2dtool.h"
2018-07-08 02:48:04 +08:00
std::map<e2d::Resource, ID2D1Bitmap*> e2d::Image::_bitmapCache;
e2d::Image::Image()
: _bitmap(nullptr)
2018-05-22 23:36:46 +08:00
, _cropRect()
{
}
e2d::Image::Image(const Resource& res)
: _bitmap(nullptr)
2018-05-22 23:36:46 +08:00
, _cropRect()
{
this->open(res);
}
e2d::Image::Image(const Resource& res, const Rect& cropRect)
: _bitmap(nullptr)
2018-05-22 23:36:46 +08:00
, _cropRect()
{
this->open(res);
this->crop(cropRect);
}
e2d::Image::Image(const String & fileName)
: _bitmap(nullptr)
2018-05-22 23:36:46 +08:00
, _cropRect()
{
this->open(Resource(fileName));
}
e2d::Image::Image(const String & fileName, const Rect & cropRect)
: _bitmap(nullptr)
2018-05-22 23:36:46 +08:00
, _cropRect()
{
this->open(Resource(fileName));
2018-05-22 23:36:46 +08:00
this->crop(cropRect);
}
e2d::Image::~Image()
{
}
bool e2d::Image::open(const Resource& res)
{
if (!res.isResource())
{
WARN_IF(res.getFileName().isEmpty(), "Image open failed! Invalid file name.");
if (res.getFileName().isEmpty())
return false;
}
if (!Image::preload(res))
{
2018-05-24 12:24:39 +08:00
WARN("Load Image from file failed!");
return false;
}
2018-07-08 02:48:04 +08:00
this->_setBitmap(_bitmapCache.at(res));
return true;
}
bool e2d::Image::open(const String & fileName)
{
return open(Resource(fileName));
}
2018-05-22 23:36:46 +08:00
void e2d::Image::crop(const Rect& cropRect)
2018-02-03 22:04:43 +08:00
{
if (_bitmap)
{
2018-07-04 12:49:05 +08:00
_cropRect.origin.x = std::min(std::max(cropRect.origin.x, 0.0), this->getSourceWidth());
_cropRect.origin.y = std::min(std::max(cropRect.origin.y, 0.0), this->getSourceHeight());
_cropRect.size.width = std::min(std::max(cropRect.size.width, 0.0), this->getSourceWidth() - cropRect.origin.x);
_cropRect.size.height = std::min(std::max(cropRect.size.height, 0.0), this->getSourceHeight() - cropRect.origin.y);
}
2018-02-03 22:04:43 +08:00
}
2018-02-27 21:07:43 +08:00
double e2d::Image::getWidth() const
2018-02-03 22:04:43 +08:00
{
2018-05-22 23:36:46 +08:00
return _cropRect.size.width;
2018-02-03 22:04:43 +08:00
}
2018-02-27 21:07:43 +08:00
double e2d::Image::getHeight() const
2018-02-03 22:04:43 +08:00
{
2018-05-22 23:36:46 +08:00
return _cropRect.size.height;
2018-02-03 22:04:43 +08:00
}
e2d::Size e2d::Image::getSize() const
2018-02-03 22:04:43 +08:00
{
2018-05-22 23:36:46 +08:00
return _cropRect.size;
}
2018-02-27 21:07:43 +08:00
double e2d::Image::getSourceWidth() const
{
if (_bitmap)
{
return _bitmap->GetSize().width;
}
else
{
return 0;
}
}
2018-02-27 21:07:43 +08:00
double e2d::Image::getSourceHeight() const
{
if (_bitmap)
{
return _bitmap->GetSize().height;
}
else
{
return 0;
}
}
e2d::Size e2d::Image::getSourceSize() const
{
if (_bitmap)
{
return Size(getSourceWidth(), getSourceHeight());
}
else
{
return Size();
}
}
2018-04-06 11:31:24 +08:00
double e2d::Image::getCropX() const
2018-02-03 22:04:43 +08:00
{
2018-05-22 23:36:46 +08:00
return _cropRect.origin.x;
2018-02-03 22:04:43 +08:00
}
2018-04-06 11:31:24 +08:00
double e2d::Image::getCropY() const
2018-02-03 22:04:43 +08:00
{
2018-05-22 23:36:46 +08:00
return _cropRect.origin.y;
2018-02-03 22:04:43 +08:00
}
2018-04-06 11:31:24 +08:00
e2d::Point e2d::Image::getCropPos() const
2018-02-03 22:04:43 +08:00
{
2018-05-22 23:36:46 +08:00
return _cropRect.origin;
2018-02-03 22:04:43 +08:00
}
bool e2d::Image::preload(const Resource& res)
{
2018-07-08 02:48:04 +08:00
if (_bitmapCache.find(res) != _bitmapCache.end())
{
return true;
}
HRESULT hr = S_OK;
IWICBitmapDecoder *pDecoder = nullptr;
IWICBitmapFrameDecode *pSource = nullptr;
IWICStream *pStream = nullptr;
IWICFormatConverter *pConverter = nullptr;
ID2D1Bitmap *pBitmap = nullptr;
IWICImagingFactory *pImagingFactory = Renderer::getImagingFactory();
if (res.isResource())
{
HRSRC imageResHandle = nullptr;
HGLOBAL imageResDataHandle = nullptr;
void *pImageFile = nullptr;
DWORD imageFileSize = 0;
// <20><>λ<EFBFBD><CEBB>Դ
imageResHandle = ::FindResourceW(
HINST_THISCOMPONENT,
MAKEINTRESOURCE(res.getResNameId()),
(LPCWSTR)res.getResType()
);
hr = imageResHandle ? S_OK : E_FAIL;
if (SUCCEEDED(hr))
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
imageResDataHandle = ::LoadResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageResDataHandle ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// <20><>ȡ<EFBFBD>ļ<EFBFBD>ָ<EFBFBD><EFBFBD><EBA3AC><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
pImageFile = ::LockResource(imageResDataHandle);
hr = pImageFile ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>С
imageFileSize = ::SizeofResource(HINST_THISCOMPONENT, imageResHandle);
hr = imageFileSize ? S_OK : E_FAIL;
}
if (SUCCEEDED(hr))
{
// <20><><EFBFBD><EFBFBD> WIC <20><>
hr = pImagingFactory->CreateStream(&pStream);
}
if (SUCCEEDED(hr))
{
// <20><>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD>
hr = pStream->InitializeFromMemory(
reinterpret_cast<BYTE*>(pImageFile),
imageFileSize
);
}
if (SUCCEEDED(hr))
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Ľ<EFBFBD><C4BD><EFBFBD><EFBFBD><EFBFBD>
hr = pImagingFactory->CreateDecoderFromStream(
pStream,
nullptr,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
}
}
else
{
String actualFilePath = File(res.getFileName()).getFilePath();
if (actualFilePath.isEmpty())
{
return false;
}
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
hr = pImagingFactory->CreateDecoderFromFilename(
(LPCWSTR)actualFilePath,
nullptr,
GENERIC_READ,
WICDecodeMetadataCacheOnLoad,
&pDecoder
);
}
if (SUCCEEDED(hr))
{
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD>ʼ<EFBFBD><CABC><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
hr = pDecoder->GetFrame(0, &pSource);
}
if (SUCCEEDED(hr))
{
// <20><><EFBFBD><EFBFBD>ͼƬ<CDBC><C6AC>ʽת<CABD><D7AA><EFBFBD><EFBFBD>
hr = pImagingFactory->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
// ͼƬ<CDBC><C6AC>ʽת<CABD><D7AA><EFBFBD><EFBFBD> 32bppPBGRA
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
nullptr,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// <20><> WIC λͼ<CEBB><CDBC><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> Direct2D λͼ
hr = Renderer::getInstance()->getRenderTarget()->CreateBitmapFromWicBitmap(
pConverter,
nullptr,
&pBitmap
);
}
if (SUCCEEDED(hr))
{
2018-07-08 02:48:04 +08:00
_bitmapCache.insert(std::make_pair(res, pBitmap));
}
// <20>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
2018-05-22 12:24:43 +08:00
SafeRelease(pDecoder);
SafeRelease(pSource);
SafeRelease(pStream);
SafeRelease(pConverter);
return SUCCEEDED(hr);
}
void e2d::Image::clearCache()
{
2018-07-08 02:48:04 +08:00
for (auto bitmap : _bitmapCache)
{
2018-05-22 12:24:43 +08:00
SafeRelease(bitmap.second);
}
2018-07-08 02:48:04 +08:00
_bitmapCache.clear();
2018-05-14 00:36:01 +08:00
}
void e2d::Image::_setBitmap(ID2D1Bitmap * bitmap)
{
if (bitmap)
{
_bitmap = bitmap;
2018-05-22 23:36:46 +08:00
_cropRect.origin.x = _cropRect.origin.y = 0;
_cropRect.size.width = _bitmap->GetSize().width;
_cropRect.size.height = _bitmap->GetSize().height;
2018-05-14 00:36:01 +08:00
}
}
ID2D1Bitmap * e2d::Image::getBitmap()
{
return _bitmap;
}