【问题标题】:Load Images from memory (libharu) from Magick++ images从 Magick++ 图像从内存 (libharu) 加载图像
【发布时间】:2012-06-01 07:01:29
【问题描述】:

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

HPDF_LoadRawImageFromMem()

根据documentation 本质上是从一些void *buffer 加载图像。

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

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

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

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

【问题讨论】:

    标签: c++ image imagemagick libharu magick++


    【解决方案1】:

    我想我回答有点晚了,但这是一个真实的答案。

    我使用 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()等方法

    【讨论】:

      【解决方案2】:

      不幸的是,我既没有使用 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 假设的原始解释具有相似的方法。 希望这至少有一点帮助...... 干杯 标记。

      【讨论】:

        【解决方案3】:

        回答永远不会迟到。

        我使用 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 文档和页面的创建。

        【讨论】:

        • 你的意思是image.write(&amp;blob, "PNG");
        • @Sam,是的,可能。我手上没有代码了。
        猜你喜欢
        • 1970-01-01
        • 1970-01-01
        • 2015-09-20
        • 1970-01-01
        • 2010-12-11
        • 1970-01-01
        • 2015-10-24
        • 1970-01-01
        • 2012-06-01
        相关资源
        最近更新 更多