首页 文章

通过适当的压缩逐页将PDF转换为TIFF

提问于
浏览
0

问题

There are PDF documents with different type of objects inside . 有简单的文字 . 可以存在B&W的扫描图像,以及其他真实颜色的图像 . 两者的分辨率都很高(~1789X2711) .

I need to convert the PDF into a set of single page TIFF files . 有很好的工具 . 例如Irfanview,ImageMagick . 问题是我必须为所有页面定义一个压缩类型 .

对所有页面使用JPG会导致B&W图像的细节丢失,与无损传真压缩相比,它们将是巨大的 .

对所有人使用无损传真会使颜色和真彩色图像的细节变得模糊 .

想法

examine the PDF page by page 会很高兴 . 我可以查看页面的内容 . 内部有什么样的图像,以及针对特定页面推荐哪种压缩 . 我认为这可以用 IText 完成,但我不确切知道, how it should be done . 第二件事是我想做这个分析 without fully reading the PDF file . 可能吗?

也许最快的解决方案是使用IText分析为每种压缩类型创建页面列表,然后调用Irfanview以适当的压缩处理选择的页面 .

欢迎任何想法和建议 .

更新:我现在有一个答案 . 它不包括所有要求,也不包括免费软件 . 任何开源创意?也许基于Java的解决方案

1 回答

  • 2

    这可以通过Atalasoft的DotImage DotPdf完成(提示必须“我在那里工作并在这些产品上工作”) . 以下是我在C#中执行此任务的方法:

    PdfImageSource source = new PdfImageSource(pdfStream);
    
    while (source.HasMoreImages()) {
        AtalaImage image = source.AcquireNext();
        string fileName = GetNextTiffName();
        using (FileStream outStm = new FileStream(fileName, FileMode.Create)) {
            TiffEncoder encoder = new TiffEncoder();
            encoder.Compression = SelectCompression(image.PixelFormat);
            image.Save(outStm, encoder, null);
        }
        source.Release(image);
    }
    
    private TiffCompression SelectCompression(PixelFormat pf)
    {
         switch (pf) {
         // 1 bit? use CCITT G4
         case PixelFormat.Pixel1bbIndexed: return TiffCompression.Group4FaxEncoding;
         // 24 bit? use JPEG
         case PixelFormat.Pixel24bppBgr: return TiffCompression.JpegCompression;
         // all else, Lzw
         default: return TiffCompression.Lzw;
         }
    }
    

    您可以使SelectCompression做任何你想做的事情 . 如果为该像素格式选择无效压缩,编码器将使用适当的无损压缩(例如,如果选择CCITT为24位颜色,则编码器将使用Lzw) .

    我们的PDF解码器知道PDF页面何时只是灰色并返回灰色图像 . 它没有做任何事情让你到1位(这是如此抗锯齿的文本看起来不错),但你可以阈值灰色图像,并查看它与灰色图像之间的总体差异,以确定它是否可以转到1位) .

    这是你如何做一组页面:

    public void ExtractNPages(Stream pdfStream, params int[] pageIndexes)
    {
        PdfImageSource source = new PdfImageSource(pdfStream);
        for (int i in pageIndexes) {
            AtalaImage image = source[i]; // implied Acquire
            string fileName = GetNextTiffName();
            using (FileStream outStm = new FileStream(fileName, FileMode.Create)) {
                TiffEncoder = new TiffEncoder();
                encoder.Compression = SelectCompression(image.PixelFormat);
                image.Save(outStm, encoder, null);
            }
            source.Release(image);
        }
     }
    

    所以现在你可以做 ExtractNPages(stm, 0, 2, 4, 6);

相关问题