c++imageimagemagicklibharumagick++

Load Images from memory (libharu) from Magick++ images


I am working on some pdf generation software in c++ based on libharu and I would like to be able to first manipulate images using Magick++ and then load them from memory using libharu function:

HPDF_LoadRawImageFromMem()

Which according to the documentation essentially load images from some void *buffer.

My goal is to be able to get this void* data out of a Magick::Image instance and load this image into my haru pdf based on this data.

I have tried writing to a void*or to a Magick::Blob but the only achievement I have had so far was some black rectangle instead of the image I am expecting.

Does anyone have any experience in converting Raw image data from one library into another one ?

The reason I am trying to do this from memory is because so far I am writing Magick::Image instances into a file and then reading from this file to load then in haru, which is a huge performance hit in the context of my Application.


Solution

  • I'm a little late to answer I guess, but here's a real-life answer.

    I successfully added an itk::Image to my pdf using LibHaru so it should work about the same for you. First, you need to know if the library you use is row major or column major. LibHaru (and all the libraries I know) works in row major, so your library should too, or you will need to "transpose" your data.

    // Black and white image (8 bits per pixel)
    itk::Image<unsigned char, 2>::Pointer image = ...;
    const unsigned char *imageData = image->GetBufferPointer();
    const HPDF_Image image = HPDF_LoadRawImageFromMem(m_Document,
        imageData, width, height, HPDF_CS_DEVICE_GRAY, 8);
    
    // Or color image (24 bits per pixel, 8 bits per color component)
    itk::Image<RGBPixel, 2>::Pointer image = ...;
    const RGBPixel *imageData = image->GetBufferPointer();
    const HPDF_Image image = HPDF_LoadRawImageFromMem(m_Document,
        reinterpret_cast<const unsigned char *>(imageData),
        width, height, HPDF_CS_DEVICE_RGB, 8);
    
    // Usual LibHaru code. EndText, Position, Draw, StartText, etc.
    // This code should not be dependant on the type
    InsertImage(image);
    

    I think the only complicated part is the reinterpret_cast. The black and white image don't need one because it's already defined as byte. For example, if you have this image

    102 255 255
     99 200   0
    255   0 100
    imageData == {102, 255, 255, 99, 200, 0, 255, 0, 100};
    

    However, if you have this color image

    (  0,   0, 255) (0, 255, 255) ( 42, 255, 242)
    (200, 200, 255) (0, 199, 199) (190, 190, 190)
    imageData == {0, 0, 255, 0, 255, 255, 42, 255, 242, 200, 200, 255, ... }
    

    which LibHaru will inderstand because you tell him to use HPDF_CS_DEVICE_RGB, which means that it will group the data in (R, G, B).

    Of course, using ImageMagick, you need to find how to access the first pixel. It's probably a method like data(), begin(), pointer(), etc.