I started playing with GDI + in Delphi 2009. Among the things I wanted to do was load a PNG resource and apply color conversion to it when drawing it to a Graphics object. I am using the code provided at http://www.bilsen.com/gdiplus/ . To do this, I just added a new constructor to TGPBitmap, which uses the same code that is located in <www.codeproject.com> /KB/GDI-plus/cgdiplusbitmap.aspx(++) or <www.masm32.com> / board / index.php? topic = 10191.0 (MASM), converted to Delphi.
For reference, the converted code is as follows:
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;
This code works fine, as I can download the downloaded image without any problems. However, if I try to apply color conversion when drawing it, I get a wonderful error: (GDI + Error) Out of Memory.
If I load a bitmap from a file or create a temporary one, to which I draw an initial raster map, and then use a temporary one, then it works just fine.
What bothers me if I take a C ++ project from codeproject , add the same PNG as a resource and use the same color conversion (in other words, do the same thing that I do in Delphi in the same order and with those the same function calls that happen in one DLL), then it works.
C ++ code is as follows:
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);
Delphic colleague:
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
I absolutely do not know what could be causing this problem, and Google did not help. Any ideas, comments and explanations are highly appreciated.