C# PDFSharp-将FlateCode提取为PNG

C# PDFSharp-将FlateCode提取为PNG,c#,pdf,pdfsharp,C#,Pdf,Pdfsharp,目标 从png的pdf中正确获取FlateCode图像对象 请让我知道,如果你看到任何错误与下面的代码,可能会导致问题 下面的代码给了我图像,但它是完全扭曲的。见:(左=好,右=我的代码) static void ExportAsPngImage(PdfDictionary图像、字符串文件名、ref int count) { int width=image.Elements.GetInteger(PdfImage.Keys.width); int height=image.Elements.G

目标 从png的pdf中正确获取FlateCode图像对象

请让我知道,如果你看到任何错误与下面的代码,可能会导致问题

下面的代码给了我图像,但它是完全扭曲的。见:(左=好,右=我的代码)

static void ExportAsPngImage(PdfDictionary图像、字符串文件名、ref int count)
{
int width=image.Elements.GetInteger(PdfImage.Keys.width);
int height=image.Elements.GetInteger(PdfImage.Keys.height);
int bitsPerComponent=image.Elements.GetInteger(PdfImage.Keys.bitsPerComponent);
var canUnfilter=image.Stream.TryUnfilter();
字节[]解码=image.Stream.Value;
System.Drawing.Imaging.PixelFormat PixelFormat;
交换机(比特组件)
{
案例1:
pixelFormat=pixelFormat.Format1Bppined;
打破
案例8:
pixelFormat=pixelFormat.Format8Bppined;
打破
案例24:
pixelFormat=pixelFormat.Format24bppRgb;
打破
违约:
抛出新异常(“未知像素格式”+bitsPerComponent);
}
位图bmp=新位图(宽度、高度、像素格式);
var bmd=bmp.LockBits(新的System.Drawing.Rectangle(0,0,宽度,高度),ImageLockMode.WriteOnly,pixelFormat);
整数长度=(整数)数学上限(转换为32(宽度)*比特组件/8.0);
对于(int j=0;j
我假设这是一张
案例8
图像。如果提取图像数据时不使用关联的调色板,并使用默认调色板显示图像,则将获得与正在显示的图像类似的图像

PDF文件中的图像可以由几个PDF对象组成:像素数据、调色板、alpha遮罩、双层遮罩


可能对于该图像,创建一个灰度调色板就足够了,其中颜色x具有RGB值(x,x,x)。但对于一般解决方案,请从PDF中提取调色板。

以下是一段代码,用于设置/DeviceRGB颜色空间的调色板:

using PdfSharp.Pdf;
using PdfSharp.Pdf.Advanced;

...

// get palette if required (pf is the pixel format, previously extracted from the imageDictionary, imageDictionary is the PdfDictionary for the image, bmp is the System.Drawing.Bitmap we're going to be dumping our image data to)
if (pf == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
{
    PdfArray colArr = imageDictionary.Elements.GetArray(PdfImage.Keys.ColorSpace);
    if (colArr != null && colArr.Elements.GetName(0) == "/Indexed" && colArr.Elements.GetName(1) == "/DeviceRGB")
    {
        System.Drawing.Imaging.ColorPalette pal = bmp.Palette;      // this returns a clone, so we'll manipulate it and then set it back at the end
        int palCount = colArr.Elements.GetInteger(2);
        char[] palVal = colArr.Elements.GetString(3).ToCharArray();
        int basePointer = 0;
        for (int i = 0; i < palCount; i++)
        {
            pal.Entries[i] = System.Drawing.Color.FromArgb(palVal[basePointer], palVal[basePointer + 1], palVal[basePointer + 2]);
            basePointer += 3;
        }
        bmp.Palette = pal;
    }
    else
    {
        // some other colorspace mechanism needs to be implemented
    }
}
使用PdfSharp.Pdf;
使用PdfSharp.Pdf.Advanced;
...
//如果需要,获取调色板(pf是像素格式,以前从imageDictionary中提取,imageDictionary是图像的PdfDictionary,bmp是我们要将图像数据转储到的System.Drawing.Bitmap)
if(pf==System.Drawing.Imaging.PixelFormat.Format8BPindexed)
{
PdfArray colArr=imageDictionary.Elements.GetArray(PdfImage.Keys.ColorSpace);
if(colArr!=null&&colArr.Elements.GetName(0)=“/index”&&colArr.Elements.GetName(1)=“/DeviceRGB”)
{
System.Drawing.Imaging.ColorPalette pal=bmp.Palette;//这将返回一个克隆,因此我们将对其进行操作,然后在最后将其设置回原处
int palCount=colArr.Elements.GetInteger(2);
char[]palVal=colArr.Elements.GetString(3.ToCharArray();
int basePointer=0;
对于(int i=0;i
您假定特定的颜色空间。为什么?只是随机测试代码-PdfSharp.Pdf.PdfArray arr=image.Elements.GetArray(PdfSharp.Pdf.Advanced.PdfImage.Keys.ColorSpace);删除了相同的结果@mklca您可以发布PDF文件的链接吗?
using PdfSharp.Pdf;
using PdfSharp.Pdf.Advanced;

...

// get palette if required (pf is the pixel format, previously extracted from the imageDictionary, imageDictionary is the PdfDictionary for the image, bmp is the System.Drawing.Bitmap we're going to be dumping our image data to)
if (pf == System.Drawing.Imaging.PixelFormat.Format8bppIndexed)
{
    PdfArray colArr = imageDictionary.Elements.GetArray(PdfImage.Keys.ColorSpace);
    if (colArr != null && colArr.Elements.GetName(0) == "/Indexed" && colArr.Elements.GetName(1) == "/DeviceRGB")
    {
        System.Drawing.Imaging.ColorPalette pal = bmp.Palette;      // this returns a clone, so we'll manipulate it and then set it back at the end
        int palCount = colArr.Elements.GetInteger(2);
        char[] palVal = colArr.Elements.GetString(3).ToCharArray();
        int basePointer = 0;
        for (int i = 0; i < palCount; i++)
        {
            pal.Entries[i] = System.Drawing.Color.FromArgb(palVal[basePointer], palVal[basePointer + 1], palVal[basePointer + 2]);
            basePointer += 3;
        }
        bmp.Palette = pal;
    }
    else
    {
        // some other colorspace mechanism needs to be implemented
    }
}