【问题标题】:FlateDecode PDF DecodingFlateDecode PDF解码
【发布时间】:2016-11-23 10:37:14
【问题描述】:

我有一个来自 iTextSharp 的结果,它可以通过 pdf 阅读器进行解析,但我希望能够获取二进制内容并手动解析它。我试过在标签<</Length 256/Filter/FlateDecode>>stream之间取文本 和 endstream并使用 .NET DeflateStream 类尝试解压缩导致此异常的文本:

System.IO.InvalidDataException: Block length does not match with its complement. at System.IO.Compression.Inflater.DecodeUncompressedBlock(Boolean& end_of_block) at System.IO.Compression.Inflater.Decode() at System.IO.Compression.Inflater.Inflate(Byte[] bytes, Int32 offset, Int32 length) at System.IO.Compression.DeflateStream.Read(Byte[] array, Int32 offset, Int32 count) at System.IO.Stream.InternalCopyTo(Stream destination, Int32 bufferSize) at FlateDecodeTest.Decompress(Byte[] data)

我的代码是:

using System;
using System.Security.Cryptography;
using System.Text;
using System.Diagnostics;
using System.IO;
using System.IO.Compression;

public class FlateDecodeTest
{
    public static void Main() 
    {
        string s = @"xœuÁN!E÷|Å...";

        byte[] b = Decompress(GetBytes(s));

        Console.WriteLine(GetString(b));
    }

    public static byte[] Decompress(byte[] data)
    {
        Console.WriteLine(data.Length);
        byte[] decompressedArray = null;
        try
        {
            using (MemoryStream decompressedStream = new MemoryStream())
            {
                using (MemoryStream compressStream = new MemoryStream(data))
                {
                    using (DeflateStream deflateStream = new DeflateStream(compressStream, CompressionMode.Decompress))
                    {
                        deflateStream.CopyTo(decompressedStream);
                    }
                }
                decompressedArray = decompressedStream.ToArray();
            }
        }
        catch (Exception exception)
        {
            Console.WriteLine(exception);
        }

        return decompressedArray;
    }

    static byte[] GetBytes(string str)
    {
        byte[] bytes = new byte[str.Length * sizeof(char)];
        System.Buffer.BlockCopy(str.ToCharArray(), 0, bytes, 0, bytes.Length);
        return bytes;
    }

    static string GetString(byte[] bytes)
    {
        char[] chars = new char[bytes.Length / sizeof(char)];
        System.Buffer.BlockCopy(bytes, 0, chars, 0, bytes.Length);
        return new string(chars);
    }
}

【问题讨论】:

  • “获取标签 <</Length 256/Filter/FlateDecode>>streamendstream 之间的文本” - 这不是那里的文本,它的二进制数据。如果您从那里获取数据作为文本,您很可能已经损坏了它。如果纯属运气没有发生这种损坏,您的GetBytes 方法会尝试完全混淆数据。使用流内容中的确切字节。

标签: c# .net pdf itext


【解决方案1】:

不要使用DeflateStream 类。如果你对某个页面的内容流感兴趣(比如说第 1 页),你可以使用这个方法:

byte[] streamBytes = reader.GetPageContent(1);

其中readerPdfReader 类的一个实例。当然,如果页面的资源字典中有 Form XObjects,这还不够。在这种情况下,您必须使用 PRStream 对象。例如:如果 Form XObject(或任何其他流对象)的对象编号为 23,那么您将得到 PRStream 对象,如下所示:

PRStream str = (PRStream)reader.GetPdfObject(23);
byte[] bytes = PdfReader.GetStreamBytes(str);

与提供原始压缩字节的GetStreamBytesRaw() 方法相反,GetStreamBytes() 方法将解压缩流。见iTextSharp: Convert PdfObject to PdfStream

如果您不知道要检查的对象的编号,您可以遍历 PDF 对象树,例如使用 PdfDictionaryPdfArrayGetAsStream() 方法,等等.

【讨论】:

    猜你喜欢
    • 1970-01-01
    • 2021-12-01
    • 1970-01-01
    • 2012-07-28
    • 2023-04-01
    • 1970-01-01
    • 1970-01-01
    • 2015-04-10
    • 2016-02-14
    相关资源
    最近更新 更多