mirror of
https://github.com/chibicitiberiu/rainmeter-studio.git
synced 2024-02-24 04:33:31 +00:00
- Added image caching system internally.
It would reduce memory usage in case that you use the same image file repeatedly on some meters. (Eg. Crop a part from same image by using ImageCrop.) - Fixed an issue that Background image isn't drawn correctly when BackgroundMode=0 and tint option is set.
This commit is contained in:
parent
f19e76e6ec
commit
8ddc383ed1
@ -2122,23 +2122,26 @@ bool CMeterWindow::ResizeWindow(bool reset)
|
|||||||
|
|
||||||
if (m_BackgroundMode == BGMODE_IMAGE)
|
if (m_BackgroundMode == BGMODE_IMAGE)
|
||||||
{
|
{
|
||||||
PixelFormat format = tempBackground->GetPixelFormat();
|
w = m_BackgroundSize.cx;
|
||||||
if (format == PixelFormat32bppARGB)
|
h = m_BackgroundSize.cy;
|
||||||
{
|
|
||||||
format = PixelFormat32bppPARGB;
|
|
||||||
}
|
|
||||||
m_Background = tempBackground->Clone(0, 0, m_BackgroundSize.cx, m_BackgroundSize.cy, format);
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
w = max(w, m_BackgroundSize.cx);
|
w = max(w, m_BackgroundSize.cx);
|
||||||
h = max(h, m_BackgroundSize.cy);
|
h = max(h, m_BackgroundSize.cy);
|
||||||
|
}
|
||||||
|
|
||||||
|
Bitmap* background = new Bitmap(w, h, CTintedImage::AdjustNonAlphaPixelFormat(tempBackground));
|
||||||
|
Graphics graphics(background);
|
||||||
|
|
||||||
|
if (m_BackgroundMode == BGMODE_IMAGE)
|
||||||
|
{
|
||||||
|
Rect r(0, 0, w, h);
|
||||||
|
graphics.DrawImage(tempBackground, r, 0, 0, w, h, UnitPixel);
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
// Scale the background to fill the whole window
|
// Scale the background to fill the whole window
|
||||||
Bitmap* background = new Bitmap(w, h, PixelFormat32bppPARGB);
|
|
||||||
|
|
||||||
Graphics graphics(background);
|
|
||||||
|
|
||||||
if (m_BackgroundMode == BGMODE_SCALED_IMAGE)
|
if (m_BackgroundMode == BGMODE_SCALED_IMAGE)
|
||||||
{
|
{
|
||||||
const RECT m = m_BackgroundMargins;
|
const RECT m = m_BackgroundMargins;
|
||||||
@ -2210,10 +2213,10 @@ bool CMeterWindow::ResizeWindow(bool reset)
|
|||||||
Rect r(0, 0, w, h);
|
Rect r(0, 0, w, h);
|
||||||
graphics.DrawImage(tempBackground, r, 0, 0, w, h, UnitPixel, &imgAttr);
|
graphics.DrawImage(tempBackground, r, 0, 0, w, h, UnitPixel, &imgAttr);
|
||||||
}
|
}
|
||||||
|
|
||||||
m_Background = background;
|
|
||||||
}
|
}
|
||||||
|
|
||||||
|
m_Background = background;
|
||||||
|
|
||||||
// Get the size form the background bitmap
|
// Get the size form the background bitmap
|
||||||
m_WindowW = m_Background->GetWidth();
|
m_WindowW = m_Background->GetWidth();
|
||||||
m_WindowH = m_Background->GetHeight();
|
m_WindowH = m_Background->GetHeight();
|
||||||
|
@ -19,11 +19,101 @@
|
|||||||
#include "StdAfx.h"
|
#include "StdAfx.h"
|
||||||
#include "TintedImage.h"
|
#include "TintedImage.h"
|
||||||
#include "ConfigParser.h"
|
#include "ConfigParser.h"
|
||||||
|
#include "System.h"
|
||||||
#include "Error.h"
|
#include "Error.h"
|
||||||
#include "Litestep.h"
|
#include "Litestep.h"
|
||||||
|
|
||||||
using namespace Gdiplus;
|
using namespace Gdiplus;
|
||||||
|
|
||||||
|
class ImageCache
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
ImageCache(Bitmap* bitmap, HGLOBAL hBuffer) : m_Bitmap(bitmap), m_hBuffer(hBuffer), m_Ref(1) {}
|
||||||
|
~ImageCache() { Dispose(); }
|
||||||
|
|
||||||
|
void AddRef() { ++m_Ref; }
|
||||||
|
void Release() { if (m_Ref > 0) { --m_Ref; } if (m_Ref == 0) { Dispose(); } }
|
||||||
|
|
||||||
|
bool IsInvalid() { return m_Ref == 0; }
|
||||||
|
//int GetRef() { return m_Ref; }
|
||||||
|
Bitmap* GetCache() { return m_Bitmap; }
|
||||||
|
|
||||||
|
private:
|
||||||
|
ImageCache() {}
|
||||||
|
ImageCache(const ImageCache& cache) {}
|
||||||
|
|
||||||
|
void Dispose() { delete m_Bitmap; m_Bitmap = NULL; if (m_hBuffer) { ::GlobalFree(m_hBuffer); m_hBuffer = NULL; } }
|
||||||
|
|
||||||
|
Bitmap* m_Bitmap;
|
||||||
|
HGLOBAL m_hBuffer;
|
||||||
|
int m_Ref;
|
||||||
|
};
|
||||||
|
|
||||||
|
class ImageCachePool
|
||||||
|
{
|
||||||
|
public:
|
||||||
|
static std::wstring CreateKey(const std::wstring& fname, FILETIME ftime, DWORD fileSize)
|
||||||
|
{
|
||||||
|
WCHAR buffer[MAX_PATH];
|
||||||
|
|
||||||
|
std::wstring key = (PathCanonicalize(buffer, fname.c_str())) ? buffer : fname;
|
||||||
|
|
||||||
|
_snwprintf_s(buffer, _TRUNCATE, L":%x%08x:%x", ftime.dwHighDateTime, ftime.dwLowDateTime, fileSize);
|
||||||
|
key += buffer;
|
||||||
|
|
||||||
|
std::transform(key.begin(), key.end(), key.begin(), ::towlower);
|
||||||
|
return key;
|
||||||
|
}
|
||||||
|
|
||||||
|
static Bitmap* GetCache(const std::wstring& key)
|
||||||
|
{
|
||||||
|
std::unordered_map<std::wstring, ImageCache*>::const_iterator iter = c_CacheMap.find(key);
|
||||||
|
if (iter != c_CacheMap.end())
|
||||||
|
{
|
||||||
|
return (*iter).second->GetCache();
|
||||||
|
}
|
||||||
|
return NULL;
|
||||||
|
}
|
||||||
|
|
||||||
|
static void AddCache(const std::wstring& key, ImageCache* cache)
|
||||||
|
{
|
||||||
|
std::unordered_map<std::wstring, ImageCache*>::const_iterator iter = c_CacheMap.find(key);
|
||||||
|
if (iter != c_CacheMap.end())
|
||||||
|
{
|
||||||
|
(*iter).second->AddRef();
|
||||||
|
//LogWithArgs(LOG_DEBUG, L"* ADD: key=%s, ref=%i", key.c_str(), (*iter).second->GetRef());
|
||||||
|
}
|
||||||
|
else if (cache)
|
||||||
|
{
|
||||||
|
c_CacheMap[key] = cache;
|
||||||
|
//LogWithArgs(LOG_DEBUG, L"* ADD: key=%s, ref=%i", key.c_str(), cache->GetRef());
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
static void RemoveCache(const std::wstring& key)
|
||||||
|
{
|
||||||
|
std::unordered_map<std::wstring, ImageCache*>::const_iterator iter = c_CacheMap.find(key);
|
||||||
|
if (iter != c_CacheMap.end())
|
||||||
|
{
|
||||||
|
ImageCache* cache = (*iter).second;
|
||||||
|
cache->Release();
|
||||||
|
//LogWithArgs(LOG_DEBUG, L"* REMOVE: key=%s, ref=%i", key.c_str(), cache->GetRef());
|
||||||
|
|
||||||
|
if (cache->IsInvalid())
|
||||||
|
{
|
||||||
|
//LogWithArgs(LOG_DEBUG, L"* EMPTY-ERASE: key=%s", key.c_str());
|
||||||
|
c_CacheMap.erase(iter);
|
||||||
|
delete cache;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private:
|
||||||
|
static std::unordered_map<std::wstring, ImageCache*> c_CacheMap;
|
||||||
|
};
|
||||||
|
std::unordered_map<std::wstring, ImageCache*> ImageCachePool::c_CacheMap;
|
||||||
|
|
||||||
|
|
||||||
#define PI (3.14159265f)
|
#define PI (3.14159265f)
|
||||||
#define CONVERT_TO_RADIANS(X) ((X) * (PI / 180.0f))
|
#define CONVERT_TO_RADIANS(X) ((X) * (PI / 180.0f))
|
||||||
|
|
||||||
@ -62,8 +152,6 @@ CTintedImage::CTintedImage(const WCHAR* name, const WCHAR** configArray, bool di
|
|||||||
|
|
||||||
m_Bitmap(),
|
m_Bitmap(),
|
||||||
m_BitmapTint(),
|
m_BitmapTint(),
|
||||||
m_hBuffer(),
|
|
||||||
m_Modified(),
|
|
||||||
m_NeedsCrop(false),
|
m_NeedsCrop(false),
|
||||||
m_NeedsTinting(false),
|
m_NeedsTinting(false),
|
||||||
m_NeedsTransform(false),
|
m_NeedsTransform(false),
|
||||||
@ -98,20 +186,16 @@ CTintedImage::~CTintedImage()
|
|||||||
*/
|
*/
|
||||||
void CTintedImage::DisposeImage()
|
void CTintedImage::DisposeImage()
|
||||||
{
|
{
|
||||||
delete m_Bitmap;
|
|
||||||
m_Bitmap = NULL;
|
|
||||||
|
|
||||||
delete m_BitmapTint;
|
delete m_BitmapTint;
|
||||||
m_BitmapTint = NULL;
|
m_BitmapTint = NULL;
|
||||||
|
|
||||||
if (m_hBuffer)
|
m_Bitmap = NULL;
|
||||||
{
|
|
||||||
::GlobalFree(m_hBuffer);
|
|
||||||
m_hBuffer = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
m_Modified.dwHighDateTime = 0;
|
if (!m_CacheKey.empty())
|
||||||
m_Modified.dwLowDateTime = 0;
|
{
|
||||||
|
ImageCachePool::RemoveCache(m_CacheKey);
|
||||||
|
m_CacheKey.clear();
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -120,46 +204,60 @@ void CTintedImage::DisposeImage()
|
|||||||
** Loads the image from file handle
|
** Loads the image from file handle
|
||||||
**
|
**
|
||||||
*/
|
*/
|
||||||
bool CTintedImage::LoadImageFromFileHandle(HANDLE fileHandle, Bitmap** pBitmap, HGLOBAL* phBuffer)
|
Bitmap* CTintedImage::LoadImageFromFileHandle(HANDLE fileHandle, DWORD fileSize, ImageCache** ppCache)
|
||||||
{
|
{
|
||||||
DWORD imageSize = GetFileSize(fileHandle, NULL);
|
HGLOBAL hBuffer = ::GlobalAlloc(GMEM_MOVEABLE, fileSize);
|
||||||
|
if (hBuffer)
|
||||||
if (imageSize != INVALID_FILE_SIZE)
|
|
||||||
{
|
{
|
||||||
HGLOBAL hBuffer = ::GlobalAlloc(GMEM_MOVEABLE, imageSize);
|
void* pBuffer = ::GlobalLock(hBuffer);
|
||||||
if (hBuffer)
|
if (pBuffer)
|
||||||
{
|
{
|
||||||
void* pBuffer = ::GlobalLock(hBuffer);
|
DWORD readBytes;
|
||||||
if (pBuffer)
|
ReadFile(fileHandle, pBuffer, fileSize, &readBytes, NULL);
|
||||||
|
::GlobalUnlock(hBuffer);
|
||||||
|
|
||||||
|
IStream* pStream = NULL;
|
||||||
|
if (::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream) == S_OK)
|
||||||
{
|
{
|
||||||
DWORD readBytes;
|
Bitmap* bitmap = Bitmap::FromStream(pStream);
|
||||||
ReadFile(fileHandle, pBuffer, imageSize, &readBytes, NULL);
|
pStream->Release();
|
||||||
::GlobalUnlock(hBuffer);
|
|
||||||
|
|
||||||
IStream* pStream = NULL;
|
if (Ok == bitmap->GetLastStatus())
|
||||||
if (::CreateStreamOnHGlobal(hBuffer, FALSE, &pStream) == S_OK)
|
|
||||||
{
|
{
|
||||||
Bitmap* bitmap = Bitmap::FromStream(pStream);
|
////////////////////////////////////////////
|
||||||
pStream->Release();
|
// Workaround to avoid image corruption with JPEG in some cases
|
||||||
|
if (CSystem::GetOSPlatform() < OSPLATFORM_7)
|
||||||
|
{
|
||||||
|
GUID guid;
|
||||||
|
bitmap->GetRawFormat(&guid);
|
||||||
|
if (guid == ImageFormatJPEG)
|
||||||
|
{
|
||||||
|
Rect r(0, 0, bitmap->GetWidth(), bitmap->GetHeight());
|
||||||
|
Bitmap* clone = new Bitmap(r.Width, r.Height, PixelFormat24bppRGB);
|
||||||
|
{
|
||||||
|
Graphics graphics(clone);
|
||||||
|
graphics.DrawImage(bitmap, r, 0, 0, r.Width, r.Height, UnitPixel);
|
||||||
|
}
|
||||||
|
delete bitmap;
|
||||||
|
bitmap = clone;
|
||||||
|
|
||||||
if (bitmap && Ok == bitmap->GetLastStatus())
|
::GlobalFree(hBuffer);
|
||||||
{
|
hBuffer = NULL;
|
||||||
*pBitmap = bitmap;
|
}
|
||||||
*phBuffer = hBuffer;
|
|
||||||
return true;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
delete bitmap;
|
|
||||||
}
|
}
|
||||||
|
////////////////////////////////////////////
|
||||||
|
*ppCache = new ImageCache(bitmap, hBuffer);
|
||||||
|
return bitmap;
|
||||||
}
|
}
|
||||||
}
|
|
||||||
|
|
||||||
::GlobalFree(hBuffer);
|
delete bitmap;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
|
::GlobalFree(hBuffer);
|
||||||
}
|
}
|
||||||
|
|
||||||
return false;
|
return NULL;
|
||||||
}
|
}
|
||||||
|
|
||||||
/*
|
/*
|
||||||
@ -184,19 +282,30 @@ void CTintedImage::LoadImage(const std::wstring& imageName, bool bLoadAlways)
|
|||||||
}
|
}
|
||||||
|
|
||||||
// Read the bitmap to memory so that it's not locked by GDI+
|
// Read the bitmap to memory so that it's not locked by GDI+
|
||||||
|
DWORD fileSize;
|
||||||
HANDLE fileHandle = CreateFile(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
HANDLE fileHandle = CreateFile(filename.c_str(), GENERIC_READ, FILE_SHARE_READ, NULL, OPEN_EXISTING, FILE_ATTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);
|
||||||
if (fileHandle != INVALID_HANDLE_VALUE)
|
if (fileHandle != INVALID_HANDLE_VALUE && (fileSize = GetFileSize(fileHandle, NULL)) != INVALID_FILE_SIZE)
|
||||||
{
|
{
|
||||||
// Compare the timestamp and filename to check if the file has been changed (don't load if it's not)
|
// Compare the filename/timestamp/filesize to check if the file has been changed (don't load if it's not)
|
||||||
FILETIME tmpTime;
|
FILETIME tmpTime;
|
||||||
GetFileTime(fileHandle, NULL, NULL, &tmpTime);
|
GetFileTime(fileHandle, NULL, NULL, &tmpTime);
|
||||||
if (bLoadAlways || CompareFileTime(&tmpTime, &m_Modified) != 0)
|
std::wstring key = ImageCachePool::CreateKey(filename, tmpTime, fileSize);
|
||||||
|
|
||||||
|
if (bLoadAlways || key != m_CacheKey)
|
||||||
{
|
{
|
||||||
DisposeImage();
|
DisposeImage();
|
||||||
|
|
||||||
if (LoadImageFromFileHandle(fileHandle, &m_Bitmap, &m_hBuffer))
|
Bitmap* bitmap = ImageCachePool::GetCache(key);
|
||||||
|
ImageCache* cache = NULL;
|
||||||
|
|
||||||
|
m_Bitmap = (bitmap) ?
|
||||||
|
bitmap :
|
||||||
|
LoadImageFromFileHandle(fileHandle, fileSize, &cache);
|
||||||
|
|
||||||
|
if (m_Bitmap)
|
||||||
{
|
{
|
||||||
m_Modified = tmpTime;
|
m_CacheKey = key;
|
||||||
|
ImageCachePool::AddCache(key, cache);
|
||||||
|
|
||||||
// Check whether the new image needs tinting (or cropping, flipping, rotating)
|
// Check whether the new image needs tinting (or cropping, flipping, rotating)
|
||||||
if (!m_NeedsCrop)
|
if (!m_NeedsCrop)
|
||||||
@ -233,11 +342,8 @@ void CTintedImage::LoadImage(const std::wstring& imageName, bool bLoadAlways)
|
|||||||
// We need a copy of the image if has tinting (or flipping, rotating)
|
// We need a copy of the image if has tinting (or flipping, rotating)
|
||||||
if (m_NeedsCrop || m_NeedsTinting || m_NeedsTransform)
|
if (m_NeedsCrop || m_NeedsTinting || m_NeedsTransform)
|
||||||
{
|
{
|
||||||
if (m_BitmapTint)
|
delete m_BitmapTint;
|
||||||
{
|
m_BitmapTint = NULL;
|
||||||
delete m_BitmapTint;
|
|
||||||
m_BitmapTint = NULL;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (m_Bitmap->GetWidth() > 0 && m_Bitmap->GetHeight() > 0)
|
if (m_Bitmap->GetWidth() > 0 && m_Bitmap->GetHeight() > 0)
|
||||||
{
|
{
|
||||||
@ -280,7 +386,7 @@ void CTintedImage::ApplyCrop()
|
|||||||
{
|
{
|
||||||
if (m_Crop.Width == 0 || m_Crop.Height == 0)
|
if (m_Crop.Width == 0 || m_Crop.Height == 0)
|
||||||
{
|
{
|
||||||
m_BitmapTint = new Bitmap(0, 0, PixelFormat32bppPARGB); // create dummy bitmap
|
m_BitmapTint = new Bitmap(0, 0, PixelFormat24bppRGB); // create dummy bitmap
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
@ -319,7 +425,7 @@ void CTintedImage::ApplyCrop()
|
|||||||
}
|
}
|
||||||
|
|
||||||
Rect r(0, 0, m_Crop.Width, m_Crop.Height);
|
Rect r(0, 0, m_Crop.Width, m_Crop.Height);
|
||||||
m_BitmapTint = new Bitmap(r.Width, r.Height, PixelFormat32bppPARGB);
|
m_BitmapTint = new Bitmap(r.Width, r.Height, AdjustNonAlphaPixelFormat(m_Bitmap));
|
||||||
|
|
||||||
Graphics graphics(m_BitmapTint);
|
Graphics graphics(m_BitmapTint);
|
||||||
graphics.DrawImage(m_Bitmap, r, x, y, r.Width, r.Height, UnitPixel);
|
graphics.DrawImage(m_Bitmap, r, x, y, r.Width, r.Height, UnitPixel);
|
||||||
@ -335,28 +441,38 @@ void CTintedImage::ApplyCrop()
|
|||||||
*/
|
*/
|
||||||
void CTintedImage::ApplyTint()
|
void CTintedImage::ApplyTint()
|
||||||
{
|
{
|
||||||
if (m_GreyScale || !CompareColorMatrix(m_ColorMatrix, &c_IdentifyMatrix))
|
bool useColorMatrix = !CompareColorMatrix(m_ColorMatrix, &c_IdentifyMatrix);
|
||||||
|
|
||||||
|
if (m_GreyScale || useColorMatrix)
|
||||||
{
|
{
|
||||||
Bitmap* original = GetImage();
|
Bitmap* original = GetImage();
|
||||||
|
Bitmap* tint;
|
||||||
|
|
||||||
ImageAttributes ImgAttr;
|
if (m_GreyScale && !useColorMatrix)
|
||||||
ImgAttr.SetColorMatrix(m_ColorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);
|
|
||||||
|
|
||||||
Rect r(0, 0, original->GetWidth(), original->GetHeight());
|
|
||||||
|
|
||||||
Bitmap* tint = new Bitmap(r.Width, r.Height, PixelFormat32bppPARGB);
|
|
||||||
|
|
||||||
Graphics graphics(tint);
|
|
||||||
|
|
||||||
if (m_GreyScale)
|
|
||||||
{
|
{
|
||||||
Bitmap* gray = TurnGreyscale(original);
|
tint = TurnGreyscale(original);
|
||||||
graphics.DrawImage(gray, r, 0, 0, r.Width, r.Height, UnitPixel, &ImgAttr);
|
|
||||||
delete gray;
|
|
||||||
}
|
}
|
||||||
else
|
else
|
||||||
{
|
{
|
||||||
graphics.DrawImage(original, r, 0, 0, r.Width, r.Height, UnitPixel, &ImgAttr);
|
ImageAttributes ImgAttr;
|
||||||
|
ImgAttr.SetColorMatrix(m_ColorMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);
|
||||||
|
|
||||||
|
Rect r(0, 0, original->GetWidth(), original->GetHeight());
|
||||||
|
|
||||||
|
tint = new Bitmap(r.Width, r.Height, PixelFormat32bppPARGB);
|
||||||
|
|
||||||
|
Graphics graphics(tint);
|
||||||
|
|
||||||
|
if (m_GreyScale)
|
||||||
|
{
|
||||||
|
Bitmap* gray = TurnGreyscale(original);
|
||||||
|
graphics.DrawImage(gray, r, 0, 0, r.Width, r.Height, UnitPixel, &ImgAttr);
|
||||||
|
delete gray;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
graphics.DrawImage(original, r, 0, 0, r.Width, r.Height, UnitPixel, &ImgAttr);
|
||||||
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
delete m_BitmapTint;
|
delete m_BitmapTint;
|
||||||
@ -378,7 +494,7 @@ Bitmap* CTintedImage::TurnGreyscale(Bitmap* source)
|
|||||||
|
|
||||||
// We need a blank bitmap to paint our greyscale to in case of alpha
|
// We need a blank bitmap to paint our greyscale to in case of alpha
|
||||||
Rect r(0, 0, source->GetWidth(), source->GetHeight());
|
Rect r(0, 0, source->GetWidth(), source->GetHeight());
|
||||||
Bitmap* bitmap = new Bitmap(r.Width, r.Height, PixelFormat32bppPARGB);
|
Bitmap* bitmap = new Bitmap(r.Width, r.Height, AdjustNonAlphaPixelFormat(source));
|
||||||
|
|
||||||
Graphics graphics(bitmap);
|
Graphics graphics(bitmap);
|
||||||
graphics.DrawImage(source, r, 0, 0, r.Width, r.Height, UnitPixel, &ImgAttr);
|
graphics.DrawImage(source, r, 0, 0, r.Width, r.Height, UnitPixel, &ImgAttr);
|
||||||
@ -429,7 +545,7 @@ void CTintedImage::ApplyTransform()
|
|||||||
|
|
||||||
if (m_Flip != RotateNoneFlipNone)
|
if (m_Flip != RotateNoneFlipNone)
|
||||||
{
|
{
|
||||||
original->RotateFlip(RotateNoneFlipNone);
|
original->RotateFlip(m_Flip);
|
||||||
}
|
}
|
||||||
|
|
||||||
delete m_BitmapTint;
|
delete m_BitmapTint;
|
||||||
@ -440,7 +556,7 @@ void CTintedImage::ApplyTransform()
|
|||||||
Bitmap* original = GetImage();
|
Bitmap* original = GetImage();
|
||||||
|
|
||||||
Rect r(0, 0, original->GetWidth(), original->GetHeight());
|
Rect r(0, 0, original->GetWidth(), original->GetHeight());
|
||||||
Bitmap* transform = new Bitmap(r.Width, r.Height, PixelFormat32bppPARGB);
|
Bitmap* transform = new Bitmap(r.Width, r.Height, AdjustNonAlphaPixelFormat(original));
|
||||||
|
|
||||||
Graphics graphics(transform);
|
Graphics graphics(transform);
|
||||||
|
|
||||||
@ -448,7 +564,7 @@ void CTintedImage::ApplyTransform()
|
|||||||
|
|
||||||
graphics.DrawImage(original, r, 0, 0, r.Width, r.Height, UnitPixel);
|
graphics.DrawImage(original, r, 0, 0, r.Width, r.Height, UnitPixel);
|
||||||
|
|
||||||
original->RotateFlip(RotateNoneFlipNone);
|
original->RotateFlip(m_Flip);
|
||||||
|
|
||||||
delete m_BitmapTint;
|
delete m_BitmapTint;
|
||||||
m_BitmapTint = transform;
|
m_BitmapTint = transform;
|
||||||
|
@ -46,6 +46,7 @@
|
|||||||
};
|
};
|
||||||
|
|
||||||
class CConfigParser;
|
class CConfigParser;
|
||||||
|
class ImageCache;
|
||||||
|
|
||||||
class CTintedImage
|
class CTintedImage
|
||||||
{
|
{
|
||||||
@ -84,6 +85,9 @@ public:
|
|||||||
void DisposeImage();
|
void DisposeImage();
|
||||||
void LoadImage(const std::wstring& imageName, bool bLoadAlways);
|
void LoadImage(const std::wstring& imageName, bool bLoadAlways);
|
||||||
|
|
||||||
|
static Gdiplus::PixelFormat AdjustNonAlphaPixelFormat(Gdiplus::Bitmap* bitmap)
|
||||||
|
{ return (bitmap->GetPixelFormat() == PixelFormat24bppRGB) ? PixelFormat24bppRGB : PixelFormat32bppPARGB; }
|
||||||
|
|
||||||
protected:
|
protected:
|
||||||
enum CROPMODE
|
enum CROPMODE
|
||||||
{
|
{
|
||||||
@ -98,7 +102,7 @@ protected:
|
|||||||
void ApplyTint();
|
void ApplyTint();
|
||||||
void ApplyTransform();
|
void ApplyTransform();
|
||||||
|
|
||||||
static bool LoadImageFromFileHandle(HANDLE fileHandle, Gdiplus::Bitmap** pBitmap, HGLOBAL* phBuffer);
|
Gdiplus::Bitmap* LoadImageFromFileHandle(HANDLE fileHandle, DWORD fileSize, ImageCache** ppCache);
|
||||||
|
|
||||||
static Gdiplus::Bitmap* TurnGreyscale(Gdiplus::Bitmap* source);
|
static Gdiplus::Bitmap* TurnGreyscale(Gdiplus::Bitmap* source);
|
||||||
static bool CompareColorMatrix(const Gdiplus::ColorMatrix* a, const Gdiplus::ColorMatrix* b);
|
static bool CompareColorMatrix(const Gdiplus::ColorMatrix* a, const Gdiplus::ColorMatrix* b);
|
||||||
@ -106,9 +110,6 @@ protected:
|
|||||||
Gdiplus::Bitmap* m_Bitmap; // The bitmap
|
Gdiplus::Bitmap* m_Bitmap; // The bitmap
|
||||||
Gdiplus::Bitmap* m_BitmapTint; // The tinted bitmap
|
Gdiplus::Bitmap* m_BitmapTint; // The tinted bitmap
|
||||||
|
|
||||||
HGLOBAL m_hBuffer;
|
|
||||||
FILETIME m_Modified;
|
|
||||||
|
|
||||||
const std::wstring m_ConfigName;
|
const std::wstring m_ConfigName;
|
||||||
const WCHAR** m_ConfigArray;
|
const WCHAR** m_ConfigArray;
|
||||||
const bool m_DisableTransform;
|
const bool m_DisableTransform;
|
||||||
@ -124,6 +125,8 @@ protected:
|
|||||||
Gdiplus::RotateFlipType m_Flip;
|
Gdiplus::RotateFlipType m_Flip;
|
||||||
Gdiplus::REAL m_Rotate;
|
Gdiplus::REAL m_Rotate;
|
||||||
|
|
||||||
|
std::wstring m_CacheKey;
|
||||||
|
|
||||||
static const Gdiplus::ColorMatrix c_GreyScaleMatrix;
|
static const Gdiplus::ColorMatrix c_GreyScaleMatrix;
|
||||||
static const Gdiplus::ColorMatrix c_IdentifyMatrix;
|
static const Gdiplus::ColorMatrix c_IdentifyMatrix;
|
||||||
|
|
||||||
|
Loading…
Reference in New Issue
Block a user