从Magick++图像中加载内存(libharu)中的图像

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

本文关键字:图像 libharu 加载 Magick++ 内存      更新时间:2023-10-16

我正在开发一些基于 libharu 的 c++ pdf 生成软件,我希望能够首先使用 Magick++ 操作图像,然后使用 libharu 函数从内存中加载它们:

HPDF_LoadRawImageFromMem()

根据文档,它基本上从某些void *缓冲区加载图像。

我的目标是能够从Magick::Image实例中获取这void*数据,并根据这些数据将此图像加载到我的haru pdf中。

我尝试过写void*Magick::Blob但到目前为止我唯一的成就是一些黑色矩形而不是我期望的图像。

有没有人有将原始图像数据从一个库转换为另一个库的经验?

我尝试从内存中执行此操作的原因是,到目前为止,我将Magick::image实例写入一个文件,然后从该文件读取以加载然后在haru中加载,这在我的应用程序上下文中是一个巨大的性能影响。

我想

我回答有点晚了,但这是一个现实生活中的答案。

我使用 LibHaru 成功地将 itk::Image 添加到我的 pdf 中,因此它对您来说应该大致相同。首先,您需要知道您使用的库是行主库还是列主库。LibHaru(以及我认识的所有库)都是行专业,所以你的库也应该这样做,否则你需要"转置"你的数据。

// 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);

我认为唯一复杂的部分是reinterpret_cast。黑白图像不需要,因为它已经定义为字节。例如,如果您有此图像

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

但是,如果您有此彩色图像

(  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, ... }

LibHaru 会因为告诉他使用HPDF_CS_DEVICE_RGB而输入,这意味着它会将数据分组到 (R, G, B) 中。

当然,使用ImageMagick,您需要找到如何访问第一个像素。它可能是一个像data(),begin(),pointer()等方法。

不幸的是,我既没有使用ImageMagic也没有libharu,但是我在图像处理方面有一些经验,由于还没有人回答,也许我可以提供帮助。问题可能是有大量的原始图像格式,我很确定两个库对这些格式的理解不同。 更糟糕的是,对libharu的原始图像解释几乎没有记录。然而,libharu处理原始数据的结论非常简单,可以从"HPDF_LoadRawImageFromMem"的参数中得出。宽度和高度几乎是不言自明的,唯一的问题是使用的(可能是像素)。 更有趣的是:"bits_per_component"。 此参数可能描述了使用多少位来定义一个像素(常见值为 8:从 256 个值的调色板中索引,16:从 65535 个值的调色板中索引,24:一个字节表示红色、绿色和蓝色 [RGB],32:作为 24 但带有 alpha 通道或 8 位表示青色、品红色、黄色、 和黑色 [CMYK],36:作为 32,但每个值有 9 位,以便于转换...... 一个问题是类型:HPDF_ColorSpace的糟糕文档,因为它可能描述了如何解释with:"bits_per_component"的颜色值。ImageMagic似乎实现了完全不同的方法。 图像对象似乎始终具有图像格式(JPEG,PNG,GIF),因此图像对象可能永远不会具有"直接"的内存表示形式,而是经过编码的。我的建议是将ImagaMagic图像切换到TIFF格式,因为它容忍压缩,因此与libharu假设的原始解释具有类似的方法。希望这至少有一点帮助...干杯 马克。

回答永远不会晚。

我使用 PNG blob 作为中间步骤:

Image image;
image.read("file.jpg");
Blob blob;
image.write(blob, "PNG");
HPDF_Image pdfImg = HPDF_LoadPngImageFromMem(doc, (const HPDF_BYTE*)blob.data(), blob.length());
HPDF_Page_DrawImage(doc, pdfImg, 0, 0, image.columns(), image.rows());

为简洁起见,省略了 PDF 文档和页面创建。