Я начал играть с GDI + в Delphi 2009. Среди прочего я хотел загрузить PNG-ресурс и применить преобразование цветов к нему при рисовании его в объекте Graphics. Я использую код, предоставленный в http://www.bilsen.com/gdiplus/.. Для этого я просто добавил новый конструктор в TGPBitmap, который использует тот же код, что и в /KB/GDI-plus/cgdiplusbitmap.aspx (C ++ ) или /board/index.php?topic=10191.0 (MASM) преобразован в Delphi.
Для справки, преобразованный код выглядит следующим образом:
constructor TGPBitmap.Create(const Instance: HInst; const PngName: String; dummy : PngResource_t);
const
cPngType : string = 'PNG';
var
hResource : HRSRC;
imageSize : DWORD;
pResourceData : Pointer;
hBuffer : HGLOBAL;
pBuffer : Pointer;
pStream : IStream;
begin
inherited Create;
hResource := FindResource(Instance, PWideChar(PngName), PWideChar(cPngType));
if hResource = 0 then Exit;
imageSize := SizeofResource(Instance, hResource);
if imageSize = 0 then Exit;
pResourceData := LockResource(LoadResource(Instance, hResource));
if pResourceData = nil then Exit;
hBuffer := GlobalAlloc(GMEM_MOVEABLE, imageSize);
if hBuffer <> 0 then
begin
try
pBuffer := GlobalLock(hBuffer);
if pBuffer <> nil then
begin
try
CopyMemory(pBuffer, pResourceData, imageSize);
if CreateStreamOnHGlobal(hBuffer, FALSE, pStream) = S_OK then
begin
GdipCheck(GdipCreateBitmapFromStream(pStream, FNativeHandle));
end;
finally
GlobalUnlock(hBuffer);
pStream := nil;
end;
end;
finally
GlobalFree(hBuffer);
end;
end;
end;
Код работает нормально, так как я могу нарисовать загруженное изображение без проблем. Однако, если я пытаюсь применить преобразование цветов при рисовании, я получаю прекрасную ошибку: (GDI + ошибка) Недостаточно памяти.
Если я загружаю растровое изображение из файла, или если я создаю временное изображение, к которому я рисую исходное растровое изображение, а затем использую временное изображение, то оно работает просто отлично.
Что меня беспокоит, так это то, что если я беру проект C ++ из codeproject , добавляю тот же PNG, что и ресурс, и использую такое же преобразование цветов (другими словами, делайте то же самое, что я делаю в Delphi) в том же порядке и с теми же вызовами функций, которые попадают в одну и ту же DLL), тогда это работает.
Код C ++ выглядит так:
const Gdiplus::ColorMatrix cTrMatrix = {
{
{1.0, 0.0, 0.0, 0.0, 0.0},
{0.0, 1.0, 0.0, 0.0, 0.0},
{0.0, 0.0, 1.0, 0.0, 0.0},
{0.0, 0.0, 0.0, 0.5, 0.0},
{0.0, 0.0, 0.0, 0.0, 1.0}
}
};
Gdiplus::ImageAttributes imgAttrs;
imgAttrs.SetColorMatrix(&cTrMatrix, Gdiplus::ColorMatrixFlagsDefault, Gdiplus::ColorAdjustTypeBitmap);
graphics.DrawImage(*pBitmap, Gdiplus::Rect(0, 0, pBitmap->m_pBitmap->GetWidth(), pBitmap->m_pBitmap->GetHeight()), 0, 0, pBitmap->m_pBitmap->GetWidth(), pBitmap->m_pBitmap->GetHeight(), Gdiplus::UnitPixel, &imgAttrs);
Аналог Delphi:
const
cTrMatrix: TGPColorMatrix = (
M: ((1.0, 0.0, 0.0, 0.0, 0.0),
(0.0, 1.0, 0.0, 0.0, 0.0),
(0.0, 0.0, 1.0, 0.0, 0.0),
(0.0, 0.0, 0.0, 0.5, 0.0),
(0.0, 0.0, 0.0, 0.0, 1.0)));
var
lImgAttrTr : IGPImageAttributes;
lBitmap : IGPBitmap;
begin
// ...
lImgAttrTr := TGPImageAttributes.Create;
lImgAttrTr.SetColorMatrix(cTrMatrix, ColorMatrixFlagsDefault, ColorAdjustTypeBitmap);
aGraphics.DrawImage
(
lBitmap,
TGPRect.Create
(
0, 0, lBitmap.Width, lBitmap.Height
),
0, 0, lBitmap.Width, lBitmap.Height,
UnitPixel,
lImgAttrTr
);
Я совершенно не понимаю, что может быть причиной проблемы, и Google не помог. Любые идеи, комментарии и объяснения высоко ценятся.