Magic_Game/core/Common/Image.cpp

216 lines
4.0 KiB
C++
Raw Normal View History

#include "..\enodes.h"
#include <map>
static std::map<size_t, ID2D1Bitmap*> s_mBitmapsFromFile;
e2d::Image::Image()
: m_pBitmap(nullptr)
2018-02-03 22:04:43 +08:00
, m_fSourceClipX(0)
, m_fSourceClipY(0)
, m_fSourceClipWidth(0)
, m_fSourceClipHeight(0)
{
}
2018-02-28 19:17:15 +08:00
e2d::Image::Image(const String & strFileName)
{
2018-03-02 23:49:57 +08:00
this->open(strFileName);
}
2018-02-28 19:17:15 +08:00
e2d::Image::Image(const String & strFileName, double nClipX, double nClipY, double nClipWidth, double nClipHeight)
{
2018-03-02 23:49:57 +08:00
this->open(strFileName);
2018-02-03 22:04:43 +08:00
this->clip(nClipX, nClipY, nClipWidth, nClipHeight);
}
e2d::Image::~Image()
{
}
2018-03-02 23:49:57 +08:00
void e2d::Image::open(const String & strFilePath)
{
WARN_IF(strFilePath.isEmpty(), "Image cannot load bitmap from NULL file name.");
2018-02-03 22:04:43 +08:00
if (strFilePath.isEmpty())
return;
if (!Image::preload(strFilePath))
{
WARN_IF(true, "Load Image from file failed!");
return;
}
m_pBitmap = s_mBitmapsFromFile.at(strFilePath.getHashCode());
2018-02-03 22:04:43 +08:00
m_fSourceClipX = m_fSourceClipY = 0;
m_fSourceClipWidth = m_pBitmap->GetSize().width;
m_fSourceClipHeight = m_pBitmap->GetSize().height;
}
2018-02-27 21:07:43 +08:00
void e2d::Image::clip(double x, double y, double width, double height)
2018-02-03 22:04:43 +08:00
{
if (m_pBitmap)
{
2018-02-03 22:04:43 +08:00
m_fSourceClipX = min(max(x, 0), this->getSourceWidth());
m_fSourceClipY = min(max(y, 0), this->getSourceHeight());
m_fSourceClipWidth = min(max(width, 0), this->getSourceWidth() - m_fSourceClipX);
m_fSourceClipHeight = min(max(height, 0), this->getSourceHeight() - m_fSourceClipY);
}
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
{
return m_fSourceClipWidth;
}
2018-02-27 21:07:43 +08:00
double e2d::Image::getHeight() const
2018-02-03 22:04:43 +08:00
{
return m_fSourceClipHeight;
}
e2d::Size e2d::Image::getSize() const
2018-02-03 22:04:43 +08:00
{
return Size(m_fSourceClipWidth, m_fSourceClipHeight);
}
2018-02-27 21:07:43 +08:00
double e2d::Image::getSourceWidth() const
{
if (m_pBitmap)
{
return m_pBitmap->GetSize().width;
}
else
{
return 0;
}
}
2018-02-27 21:07:43 +08:00
double e2d::Image::getSourceHeight() const
{
if (m_pBitmap)
{
return m_pBitmap->GetSize().height;
}
else
{
return 0;
}
}
e2d::Size e2d::Image::getSourceSize() const
{
if (m_pBitmap)
{
return Size(getSourceWidth(), getSourceHeight());
}
else
{
return Size();
}
}
2018-02-27 21:07:43 +08:00
double e2d::Image::getClipX() const
2018-02-03 22:04:43 +08:00
{
return m_fSourceClipX;
}
2018-02-27 21:07:43 +08:00
double e2d::Image::getClipY() const
2018-02-03 22:04:43 +08:00
{
return m_fSourceClipY;
}
e2d::Point e2d::Image::getClipPos() const
2018-02-03 22:04:43 +08:00
{
return Point(m_fSourceClipX, m_fSourceClipY);
2018-02-03 22:04:43 +08:00
}
bool e2d::Image::preload(const String & fileName)
{
if (s_mBitmapsFromFile.find(fileName.getHashCode()) != s_mBitmapsFromFile.end())
{
return true;
}
HRESULT hr = S_OK;
IWICBitmapDecoder *pDecoder = nullptr;
IWICBitmapFrameDecode *pSource = nullptr;
IWICStream *pStream = nullptr;
IWICFormatConverter *pConverter = nullptr;
ID2D1Bitmap *pBitmap = nullptr;
// <20><><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>
hr = Renderer::getIWICImagingFactory()->CreateDecoderFromFilename(
2017-12-11 18:17:24 +08:00
fileName,
NULL,
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>
// (DXGI_FORMAT_B8G8R8A8_UNORM + D2D1_ALPHA_MODE_PREMULTIPLIED).
hr = Renderer::getIWICImagingFactory()->CreateFormatConverter(&pConverter);
}
if (SUCCEEDED(hr))
{
// ͼƬ<CDBC><C6AC>ʽת<CABD><D7AA><EFBFBD><EFBFBD> 32bbpPBGRA
hr = pConverter->Initialize(
pSource,
GUID_WICPixelFormat32bppPBGRA,
WICBitmapDitherTypeNone,
NULL,
0.f,
WICBitmapPaletteTypeMedianCut
);
}
if (SUCCEEDED(hr))
{
// <20><> WIC λͼ<CEBB><CDBC><EFBFBD><EFBFBD>һ<EFBFBD><D2BB> Direct2D λͼ
hr = Renderer::getRenderTarget()->CreateBitmapFromWicBitmap(
pConverter,
NULL,
&pBitmap
);
}
if (SUCCEEDED(hr))
{
// <20><><EFBFBD><EFBFBD>ͼƬָ<C6AC><D6B8><EFBFBD><EFBFBD>ͼƬ<CDBC><C6AC> Hash <20><>
s_mBitmapsFromFile.insert(
std::map<size_t, ID2D1Bitmap*>::value_type(
fileName.getHashCode(),
pBitmap)
);
}
// <20>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
SafeReleaseInterface(&pDecoder);
SafeReleaseInterface(&pSource);
SafeReleaseInterface(&pStream);
SafeReleaseInterface(&pConverter);
return SUCCEEDED(hr);
}
void e2d::Image::clearCache()
{
2018-02-03 22:04:43 +08:00
for (auto child : s_mBitmapsFromFile)
{
2018-02-03 22:04:43 +08:00
SafeReleaseInterface(&child.second);
}
s_mBitmapsFromFile.clear();
}
ID2D1Bitmap * e2d::Image::getBitmap()
{
return m_pBitmap;
}