I could not find this anywhere so I had to experiment:
Status := MagickSetImageFormat(FWand, PAnsiChar('BMP')); // check status here
Then we get it as a blob by calling MagickGetImageBlob.
var Size: Cardinal; blob: Pointer; begin blob := MagickGetImageBlob(FWand, @Size); // check if blob is assigned
Note that the memory for the blob is allocated by the dll, we will have to pass it to MagickRelinquishMemory to free it later.
The easiest way I found to assign some memory to a TBitmap is TBitmap.LoadFromStream. The stream in this case could be a TMemoryStream, but unfortunately there is no way to create a TMemoryStream for an existing memory block. So I wrote a descendant of TCustomMemoryStream that provides this functionality.
type TdzMagickBlob = class(TCustomMemoryStream) public constructor Create(_Memory: Pointer; _Size: Cardinal); destructor Destroy; override; end; constructor TdzMagickBlob.Create(_Memory: Pointer; _Size: Cardinal); begin inherited Create; SetPointer(_Memory, _Size); end; destructor TdzMagickBlob.Destroy; begin if Size <> 0 then MagickRelinquishMemory(Memory); inherited; end;
Remember what I said above about passing the blob back to the dll to free the memory? That’s what the destructor does.
Now we only need to load the bitmap from the stream:
bmp := TBitmap.Create; blobStream := TdzMagickBlob.Create(blob, size); try blobStream.Position := 0; bmp.LoadFromStream(blobStream); finally FreeAndNil(blobStream); end;
There we go: The image has been assigned to the TBitmap object.
I would have liked to omit the stream and directly assign the memory to TBitmap.Scanline, but I found no easy way to do that.
This is part of the object oriented layer I wrote for encapsulating (some of) the MagickWand functionality. I will put this code into my dzlib later.