Assigning an ImageMagick wand picture to a Delphi TBitmap

 Delphi  Comments Off on Assigning an ImageMagick wand picture to a Delphi TBitmap
Dec 062019

I could not find this anywhere so I had to experiment:

I mentioned PascalMagick before and that it’s part of the FreePascal RTL.

The following assigns an image that has been processed with the Magick Wand API of ImageMagick to a Delphi TBitmap.

First, we need to convert the image to bitmap format using MagickSetFormat:

  Status := MagickSetImageFormat(FWand, PAnsiChar('BMP'));
  // check status here

Then we get it as a blob by calling MagickGetImageBlob.

  Size: Cardinal;
  blob: Pointer;
  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.

  TdzMagickBlob = class(TCustomMemoryStream)
    constructor Create(_Memory: Pointer; _Size: Cardinal);
    destructor Destroy; override;

constructor TdzMagickBlob.Create(_Memory: Pointer; _Size: Cardinal);
  inherited Create;
  SetPointer(_Memory, _Size);

destructor TdzMagickBlob.Destroy;
  if Size <> 0 then

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);
    blobStream.Position := 0;

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.

 Posted by on 2019-12-06 at 09:54