【问题标题】:Using pdfbox to convert a color PDF to a b/w tiff使用 pdfbox 将彩色 PDF 转换为黑白 tiff
【发布时间】:2016-05-04 20:02:49
【问题描述】:

我在将某些彩色 PDF 转换为 tiff 图像时遇到了一点问题。我遇到问题的 PDF 文件有用蓝色墨水书写的手写签名。这些签名不会出现在生成的二进制 tiff 中。我怀疑某处有一个阈值来确定哪些像素是黑色的,哪些是白色的。

@SuppressWarnings("serial")
private static void convertPdfToTiff(final File pdf, final File tif) throws Exception {
    try 
    {
        final Iterator<ImageWriter> imageWriterIterator = ImageIO.getImageWritersByFormatName("TIF");
        final ImageWriter imageWriter = imageWriterIterator.hasNext() ? imageWriterIterator.next() : null;

        final TIFFImageWriteParam writeParam = new TIFFImageWriteParam(Locale.getDefault());
        writeParam.setCompressionMode(TIFFImageWriteParam.MODE_EXPLICIT);
        writeParam.setCompressionType("LZW");

        PDDocument pdfDocument = PDDocument.load(pdf);
        PDFRenderer pdfRenderer = new PDFRenderer(pdfDocument);

        OutputStream out = new FileOutputStream(tif);
        final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(out);
        final ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(bufferedOutputStream);
        imageWriter.setOutput(imageOutputStream);
        imageWriter.prepareWriteSequence(null);

        int pageCounter = 0;
        for (PDPage page : pdfDocument.getPages()) 
        {
            BufferedImage image = pdfRenderer.renderImageWithDPI(pageCounter, 300, ImageType.BINARY);

            final IIOImage s = new IIOImage(image, null, new TIFFImageMetadata(new TIFFIFD(new Vector<BaselineTIFFTagSet>() 
            {
                {
                       add(BaselineTIFFTagSet.getInstance());
                }
            }))) 

            {   
                {
                       final TIFFImageMetadata tiffMetadata = (TIFFImageMetadata) getMetadata();
                       final TIFFIFD rootIFD = tiffMetadata.getRootIFD();
                       final BaselineTIFFTagSet base = BaselineTIFFTagSet.getInstance();
                       rootIFD.addTIFFField(new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_X_RESOLUTION), TIFFTag.TIFF_RATIONAL, 1, new long[][] { { 300, 1 } }));
                       rootIFD.addTIFFField(new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_Y_RESOLUTION), TIFFTag.TIFF_RATIONAL, 1, new long[][] { { 300, 1 } }));
                }
            };

            imageWriter.writeToSequence(s, writeParam);
            pageCounter++;
        }

        imageWriter.dispose();
        imageOutputStream.flush();
        imageOutputStream.close();
        bufferedOutputStream.flush();
        bufferedOutputStream.close();
        pdfDocument.close();
        out.flush();
        out.close();
    } 
    catch (Exception e) 
    {
        e.printStackTrace();
        throw e;
    }
}

【问题讨论】:

    标签: pdf pdfbox tiff image-conversion


    【解决方案1】:

    前段时间我遇到了同样的问题(蓝色签名),我这样做了:

    • 渲染为 RGB
    • 使用来自JH Labs 的过滤器转换为黑白(this answer 中的评论指出了这一点)
    • 我最初尝试了抖动和扩散滤镜
    • 最适合我的过滤器是gain filterdiffusion filter 的偏差部分(我想我使用了0.3)。
    • 您可以将两个过滤器与compound filter 结合使用。
    • jhlabs 的东西不能以 .jar 文件的形式提供,但您可以下载源代码并将其添加到您的项目中
    • some examples

    顺便说一句,不要将文件保存为 LZW,而是保存为 G4,这会使它们更小。 PDFBox 具有有效保存到图像中的方法,请参阅here。如果您的 BufferedImage 是 BITONAL 类型,ImageIOUtil.writeImage() 将保存到 G4 压缩 TIFF。

    【讨论】:

    • 感谢您的回复。这给了我将图像渲染为 ImageType.GRAY 的想法,同时创建一个新的二进制缓冲图像并将灰度图像绘制到新的二进制图像中。
    【解决方案2】:

    我最终将图像渲染为灰度并将其重新绘制为第二张 bw 图像。

    @SuppressWarnings("serial")
    private static void convertPdfToTiff(final File pdf, final File tif) throws Exception {
        try 
        {
            final Iterator<ImageWriter> imageWriterIterator = ImageIO.getImageWritersByFormatName("TIF");
            final ImageWriter imageWriter = imageWriterIterator.hasNext() ? imageWriterIterator.next() : null;
    
            final TIFFImageWriteParam writeParam = new TIFFImageWriteParam(Locale.getDefault());
            writeParam.setCompressionMode(TIFFImageWriteParam.MODE_EXPLICIT);
            writeParam.setCompressionType("CCITT T.6");
    
            PDDocument pdfDocument = PDDocument.load(pdf);
            PDFRenderer pdfRenderer = new PDFRenderer(pdfDocument);
    
            OutputStream out = new FileOutputStream(tif);
            final BufferedOutputStream bufferedOutputStream = new BufferedOutputStream(out);
            final ImageOutputStream imageOutputStream = ImageIO.createImageOutputStream(bufferedOutputStream);
            imageWriter.setOutput(imageOutputStream);
            imageWriter.prepareWriteSequence(null);
    
            int pageCounter = 0;
            for (PDPage page : pdfDocument.getPages()) 
            {
                BufferedImage image = pdfRenderer.renderImageWithDPI(pageCounter, 300, ImageType.GRAY);
                BufferedImage image2 = new BufferedImage(image.getWidth(), image.getHeight(), BufferedImage.TYPE_BYTE_BINARY);
                Graphics2D g = image2.createGraphics();
                g.drawRenderedImage(image, null);
                g.dispose();
    
                final IIOImage s = new IIOImage(image2, null, new TIFFImageMetadata(new TIFFIFD(new Vector<BaselineTIFFTagSet>() 
                {
                    {
                           add(BaselineTIFFTagSet.getInstance());
                    }
                }))) 
    
                {   
                    {
                           final TIFFImageMetadata tiffMetadata = (TIFFImageMetadata) getMetadata();
                           final TIFFIFD rootIFD = tiffMetadata.getRootIFD();
                           final BaselineTIFFTagSet base = BaselineTIFFTagSet.getInstance();
                           rootIFD.addTIFFField(new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_X_RESOLUTION), TIFFTag.TIFF_RATIONAL, 1, new long[][] { { 300, 1 } }));
                           rootIFD.addTIFFField(new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_Y_RESOLUTION), TIFFTag.TIFF_RATIONAL, 1, new long[][] { { 300, 1 } }));
                    }
                };
    
                imageWriter.writeToSequence(s, writeParam);
                pageCounter++;
            }
    
            imageWriter.dispose();
            imageOutputStream.flush();
            imageOutputStream.close();
            bufferedOutputStream.flush();
            bufferedOutputStream.close();
            pdfDocument.close();
            out.flush();
            out.close();
        } 
        catch (Exception e) 
        {
            e.printStackTrace();
            throw e;
        }
    }
    

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 2018-07-02
      • 1970-01-01
      • 2021-05-02
      • 2010-10-08
      • 1970-01-01
      • 2010-11-13
      • 1970-01-01
      • 2011-02-11
      相关资源
      最近更新 更多