Magic_Game/core/Common/Image.cpp

222 lines
4.1 KiB
C++
Raw Blame History

This file contains ambiguous Unicode characters

This file contains Unicode characters that might be confused with other characters. If you think that this is intentional, you can safely ignore this warning. Use the Escape button to reveal them.

#include "..\enodes.h"
#include <map>
static std::map<size_t, ID2D1Bitmap*> s_mBitmapsFromFile;
e2d::Image::Image()
: m_pBitmap(nullptr)
, m_fSourceClipX(0)
, m_fSourceClipY(0)
, m_fSourceClipWidth(0)
, m_fSourceClipHeight(0)
{
}
e2d::Image::Image(LPCTSTR strFileName)
{
this->loadFrom(strFileName);
}
e2d::Image::Image(LPCTSTR strFileName, float nClipX, float nClipY, float nClipWidth, float nClipHeight)
{
this->loadFrom(strFileName);
this->clip(nClipX, nClipY, nClipWidth, nClipHeight);
}
e2d::Image::~Image()
{
}
void e2d::Image::loadFrom(const String & strFilePath)
{
WARN_IF(strFilePath.isEmpty(), "Image cannot load bitmap from NULL file name.");
if (strFilePath.isEmpty())
return;
if (!Image::preload(strFilePath))
{
WARN_IF(true, "Load Image from file failed!");
return;
}
m_pBitmap = s_mBitmapsFromFile.at(strFilePath.hash());
m_fSourceClipX = m_fSourceClipY = 0;
m_fSourceClipWidth = m_pBitmap->GetSize().width;
m_fSourceClipHeight = m_pBitmap->GetSize().height;
}
void e2d::Image::loadFrom(const String & strFilePath, float x, float y, float width, float height)
{
loadFrom(strFilePath);
clip(x, y, width, height);
}
void e2d::Image::clip(float x, float y, float width, float height)
{
if (m_pBitmap)
{
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);
}
}
float e2d::Image::getWidth() const
{
return m_fSourceClipWidth;
}
float e2d::Image::getHeight() const
{
return m_fSourceClipHeight;
}
e2d::Size e2d::Image::getSize() const
{
return Size(m_fSourceClipWidth, m_fSourceClipHeight);
}
float e2d::Image::getSourceWidth() const
{
if (m_pBitmap)
{
return m_pBitmap->GetSize().width;
}
else
{
return 0;
}
}
float 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();
}
}
float e2d::Image::getClipX() const
{
return m_fSourceClipX;
}
float e2d::Image::getClipY() const
{
return m_fSourceClipY;
}
e2d::Point e2d::Image::getClipPos() const
{
return Point(m_fSourceClipX, m_fSourceClipY);
}
bool e2d::Image::preload(const String & fileName)
{
if (s_mBitmapsFromFile.find(fileName.hash()) != 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(
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.hash(),
pBitmap)
);
}
// <20>ͷ<EFBFBD><CDB7><EFBFBD><EFBFBD><EFBFBD><EFBFBD><EFBFBD>Դ
SafeReleaseInterface(&pDecoder);
SafeReleaseInterface(&pSource);
SafeReleaseInterface(&pStream);
SafeReleaseInterface(&pConverter);
return SUCCEEDED(hr);
}
void e2d::Image::clearCache()
{
for (auto child : s_mBitmapsFromFile)
{
SafeReleaseInterface(&child.second);
}
s_mBitmapsFromFile.clear();
}
ID2D1Bitmap * e2d::Image::getBitmap()
{
return m_pBitmap;
}