使用pdfbox将彩色PDF转换为黑白tiff

使用pdfbox将彩色PDF转换为黑白tiff,pdf,pdfbox,tiff,image-conversion,Pdf,Pdfbox,Tiff,Image Conversion,我有点问题转换一些彩色PDF到tiff图像。我遇到问题的PDF文件都是用蓝墨水手写的签名。这些签名不会出现在生成的二进制TIFF中。我怀疑某个地方有一个阈值来决定哪些像素是黑色的,哪些是白色的 @SuppressWarnings("serial") private static void convertPdfToTiff(final File pdf, final File tif) throws Exception { try { final Iterator

我有点问题转换一些彩色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;
    }
}

不久前,我也遇到了同样的问题,蓝色签名,我做到了:

渲染为RGB 转换为b/w与过滤器从我得到了指向这一点的评论中 我最初尝试了抖动和扩散过滤器 最适合我的过滤器是偏置部分,我想我使用了0.3的加上。 您可以将两个过滤器与。 jhlabs文件不能作为.jar文件提供,但是您可以下载源代码并将其添加到您的项目中
顺便说一句,保存你的文件不是LZW,而是G4,这样会使它们变小。PDFBox具有高效保存到图像的方法,请参阅。如果您的BuffereImage类型为Bitional,则ImageIOUtil.writeImage将保存到G4 compressed TIFF。

我不久前也遇到过同样的问题蓝色签名,我这样做了:

渲染为RGB 转换为b/w与过滤器从我得到了指向这一点的评论中 我最初尝试了抖动和扩散过滤器 最适合我的过滤器是偏置部分,我想我使用了0.3的加上。 您可以将两个过滤器与。 jhlabs文件不能作为.jar文件提供,但是您可以下载源代码并将其添加到您的项目中
顺便说一句,保存你的文件不是LZW,而是G4,这样会使它们变小。PDFBox具有高效保存到图像的方法,请参阅。如果您的BuffereImage类型为Bitional,ImageIOUtil.writeImage将保存为G4压缩TIFF。

我最终将图像渲染为灰度,并将其重新绘制为第二个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;
    }
}

最后,我将图像渲染为灰度,并将其重新绘制为第二个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;
    }
}

谢谢你的回复。这让我想到了在创建一个新的二进制缓冲区图像的同时将图像渲染为ImageType.GRAY,并将灰色图像绘制成新的二进制图像。感谢您的回复。这让我想到了将图像渲染为ImageType.GRAY,同时创建一个新的二进制缓冲区图像,并将灰色图像绘制到新的二进制图像中。