使用C+将PDF格式的图像数据(PDEImage)转换为DIB+;?

使用C+将PDF格式的图像数据(PDEImage)转换为DIB+;?,pdf,dib,Pdf,Dib,我正在尝试提取PDF中的所有图像,然后将它们转换为DIB格式。第一部分很简单。我提取PDF中的所有内容,然后对它们进行迭代,每当我找到一个PDEImage时,我就将它们放入一个数组中 但我不知道如何进行第二部分。看起来所有AVConversion方法都允许您将整个PDF页面(不仅仅是图像)转换为其他格式 我有没有办法完成这项任务?提前谢谢 编辑:进一步阐述问题。 我用Visual C++编写了一个Adobe AutoBAT插件,使用.NETFramework 4。 插件的目的是(除其他外)从PD

我正在尝试提取PDF中的所有图像,然后将它们转换为DIB格式。第一部分很简单。我提取PDF中的所有内容,然后对它们进行迭代,每当我找到一个PDEImage时,我就将它们放入一个数组中

但我不知道如何进行第二部分。看起来所有AVConversion方法都允许您将整个PDF页面(不仅仅是图像)转换为其他格式

我有没有办法完成这项任务?提前谢谢

编辑:进一步阐述问题。

我用Visual C++编写了一个Adobe AutoBAT插件,使用.NETFramework 4。 插件的目的是(除其他外)从PDF文件中提取图像数据,然后将这些数据转换为DIB。需要转换为DISs是因为我将这些DIB传递给另一个库,该库对它们执行一些图像校正工作

现在我的问题是如何将PDF中的图像数据转换为DIB。PDF上的图像数据以称为PDEImage(Ref-Link)的格式存在,其中显然包含图像的所有颜色数据。现在,我使用以下代码从图像中提取上述图像数据位,并与CreateCompatibleBitmap()和SetBitmapBits()一起使用,以获得HBITMAP句柄。然后,我将其与其他必要参数一起传递给GetDIBits(),以获得一个字节数组形式的DIB,如MSDN中所述

void GetDIBImage(PDEElement element)
{
    //Obtaining a PDEImage
    PDEImage image;
    memset(&image, 0, sizeof(PDEImage));
    image = (PDEImage)element;

    //Obtaining attributes (such as width, height)
    //of the image for later use
    PDEImageAttrs attrs;
    memset(&attrs, 0, sizeof(attrs));
    PDEImageGetAttrs(image, &attrs, sizeof(attrs));

    //Obtainig image data from PDEImage to a byte array
    ASInt32 len = PDEImageGetDataLen(image);
    byte *data = (byte *)malloc(len);
    PDEImageGetData(image, 0, data);

    //Creating a DDB using said data
    HDC hdc = CreateCompatibleDC(NULL); 
    HBITMAP hBmp = CreateCompatibleBitmap(hdc, attrs.width, attrs.height);  
    LONG bitsSet = SetBitmapBits(hBmp, len, data);  //Here bitsSet gets a value of 59000 which is close to the image's actual size

    //Buffer which GetDIBits() will fill with DIB data
    unsigned char* buff = new unsigned char[len];

    //BITMAPINFO stucture to be passed to GetDIBits()
    BITMAPINFO bmpInfo;
    memset(&bmpInfo, 0, sizeof(bmpInfo));

    bmpInfo.bmiHeader.biSize = sizeof(BITMAPINFOHEADER);
    bmpInfo.bmiHeader.biWidth = (LONG)attrs.width;
    bmpInfo.bmiHeader.biHeight = (LONG)attrs.height;
    bmpInfo.bmiHeader.biPlanes = 1;
    bmpInfo.bmiHeader.biBitCount = 8;
    bmpInfo.bmiHeader.biCompression = BI_RGB;
    bmpInfo.bmiHeader.biSizeImage = ((((bmpInfo.bmiHeader.biWidth * bmpInfo.bmiHeader.biBitCount) + 31) & ~31) >> 3) * bmpInfo.bmiHeader.biHeight;  
    bmpInfo.bmiHeader.biXPelsPerMeter = 0;
    bmpInfo.bmiHeader.biYPelsPerMeter = 0;
    bmpInfo.bmiHeader.biClrUsed = 0;
    bmpInfo.bmiHeader.biClrImportant = 0;

    //Callling GetDIBits()
    //Here scanLines get a value of 0, while buff receives no data.
    int scanLines = GetDIBits(hdc, hBmp, 0, attrs.height, &buff, &bmpInfo, DIB_RGB_COLORS);

    if(scanLines > 0)
    {
        MessageBox(NULL, L"SUCCESS", L"Message", MB_OK);
    }
    else
    {
        MessageBox(NULL, L"FAIL", L"Message", MB_OK);
    }
}
以下是我的问题/担忧

  • 我使用CreateCompatibleDC()、CreateCompatibleBitmap()和SetBitmapBits()函数的方式正确吗?我的想法是使用CreateCompatibleDC()获取当前DC,然后使用CreateCompatibleBitmap()创建DDB,然后使用SetBitmapBits()将实际数据设置为DDB。对吗

  • 我创建BITMAPINFO结构的方式有问题吗。我假设它需要包含我最终获得的DIB格式的所有细节

  • 为什么在调用GetDIBits()时,不能将位图数据作为DIB提供给buff


  • 我不知道您用于访问PDF文件内部结构的库,但手头的问题将有不同于树的子问题:

  • 查找PDF文件中的所有图像
  • 将图像解码为其组件
  • 将解码图像转换为DIB
  • 查找所有图像

    图像可以出现在内容流中,也可以出现在附加到词典的流中。要查找内容流中的所有图像,您需要查找页面、XObject或模式中的所有内容流。每个XObject都可以有一个参考所有XObject的Resources->XObject字典(XObject可以是图像)

    如果您避免使用内联图像,您可以简单地扫描PDF文件,并且可以解码XObject子类型图像类型的每个dectionary

    解码

    PDF文件中独立对象的所有流(内联内容流)都经过编码,mught需要使用解码数组进行后处理。有几个过滤器,你需要能够执行解码。平板解码(ZLIB)、JPEG和CCITT(传真G3/G4)可能是最常用于图像的。希望您使用的PDF库知道如何解码流

    接下来是解码阵列(有点罕见),其中每个颜色分量都可以从输入值缩放到输出值。这是一个线性变换

    点播

    接下来是将解码图像转换为DIB。这意味着您需要将颜色组件转换为Windows可以“获取”的内容(例如,RGB.PDF的调色板、灰度(特殊调色板)。PDF支持非常多种颜色空间,将它们转换为RGB并非易事。您最希望的是,您需要处理的PDF只使用一个选择子集(如RGB和调色板)。现在,只需创建位图标头(BITMAPINFO),填写所有数据并调用DIB创建函数CreateDIBSection,即可创建DIB,并按照应用程序需要的方式处理DIB

    结语


    总而言之:要处理所有PDF文件并查找所有图像是一项艰巨的任务,如果您控制PDF的源文件,并且您知道它们始终是DeviceRGB格式,始终是JPEG等格式,并且从未内联到内容流中,这是可以做到的。

    1.查找所有图像我想转换为XObject的PDEImage对象,对吗?我没有p浏览每个PDF页面的内容并获取它们,我可以做得很好。2.解码这就是我认为我的问题所在。我的印象是PDEImageGetData(图像,0,数据)将用图像中的颜色数据填充数据缓冲区。我对PDF非常陌生,所以我不确定你所说的解码是什么意思。你是否碰巧有一个代码样本?3.对于DIB,我想我可以使用CreateDIBSection来实现此目的。那么,如果我只是将上面获得的数据数组传递给它,它会不会工作?@Sach:我不知道你在解码什么r PDF库已经有了。但是我们假设它没有解码流。现在最常用的两种颜色/调色板图像编码是Flate(ZLib)和JPEG解码。因此,如果您知道如何使用ZLib并拥有JPEG解码器,那么您的代码可能如下所示:打开PDF文件->扫描文件中的所有对象。如果对象是一个字典,并且有一个流,并且type=XObject ans子类型是Image->decode stream(如果需要)。现在您有了可以馈送到DIB的原始字节,前提是且仅当使用的颜色空间不受支持时由windows进行orted。如果是实验室或分离的颜色空间…我不明白你说“如果需要解码流”的位置。我要做的是,提取PDEImage对象,然后我想将它们转换为DIB,以便发送这些DIB(以字节数组形式)我不熟悉ZLib,也不熟悉如何解码图像。我有幸知道颜色空间只能是sRGB或AdobeRGB中的一种。Sach:PDF