包含JBIG2图像打印PDF(Print PDF that contains JBIG2 image

2019-07-31 03:15发布

请给我建议一些库,这将有助于我打印包含JBIG2编码的图像的PDF文件。 PDFRendererPDFBox不帮我。 这些库可以打印简单的PDF,但包含JBIG2图像不PDF。 PDFRenderer尝试(根据上PDFRedndrer的bug跟踪系统漏洞问题)来解决它,但有些页面仍(尤其是条形码存在)不希望打印。

PS我使用javax.print小程序API

谢谢!

更新 :也试过ICEPdf,太不想工作。

我来,所有这些库(PDFRenderer,ICEPdf,PDFBox的)使用结束JPedals JBIG2解码器 。 错误(某些页面未打印)来自这个解码器库。 该解码器的开源版本(在PDFRenderer使用,ICEPdf,PDFBox的)不再支持,但JPedal有项目的一个新的商业分支,他们写道,该bug已被固定在新的商业版本,它的价格$ 9K。

有任何想法吗?

更新2:昨天我试图取代JPedal的免费图书馆与其他开源jbig2-imageio库。 但我却没有得到任何成功的结果,所以我创建自己的项目页面上的一个新课题(谷歌代码的论坛- 在这里 )。 将感谢任何帮助。

我还发现了一些有益的讨论Apache PDFBox错误跟踪器: 在这里和这里 。

Answer 1:

有通过Borisvl位于JPedal库的叉子

https://github.com/Borisvl/JBIG2-Image-Decoder#readme

其中包含的速度提升,我相信这也应该解决您的错误。

编辑:该错误是涉及到简单的范围检查。 基本上你需要防止GetPixel访问位图范围之外的x,y值。

您需要确保下列条件调用getPixel之前得到满足

山口> = 0和col <bitmap.width行> = 0和行<bitmap.height

这是一对夫妇的小范围的检查,一些Delphi代码。 我无法测试Java代码自己,但你需要更改为src /组织/ jpedal / JBIG2 /图像/ JBIG2Bitmap.java

procedure TJBIG2Bitmap.combine(bitmap: TJBIG2Bitmap; x, y: Integer; combOp: Int64);
...
...
var
begin
  srcWidth := bitmap.width;
  srcHeight := bitmap.height;
  srcRow := 0;
  srcCol := 0;

  if (x < 0) then x := 0;
  if (y < 0) then y := 0;

  for row := y to Min(y + srcHeight - 1, Self.height - 1) do   // <<<<<<<<  HERE
  begin
    for col := x to x + srcWidth - 1 do
    begin
      srcPixel := bitmap.getPixel(srcCol, srcRow);

安德鲁。



Answer 2:

通过在YMS答案即您的评论会。 “但我可以用什么库和(更重要的)中提取图像将它们放回PDF?”

下面是一个简单的演示
1)提取jbig2或者你可以从说所有图像pdf
2)转换jbig2图像任何其他格式,在我的情况下,它jpeg
3)创建新pdf包含jpeg

使用库JBIG2-的ImageIO和iText的 。

在下面的示例,请更改资源目录路径 ,按您的需要。
为此,我不得不通过多种资源,我将在最后附上。 希望这可以帮助。

import com.itextpdf.text.Document;
import com.itextpdf.text.Image;
import com.itextpdf.text.pdf.PdfPCell;
import com.itextpdf.text.pdf.PdfPTable;
import com.itextpdf.text.pdf.PdfReader;
import com.itextpdf.text.pdf.PdfWriter;
import com.itextpdf.text.pdf.parser.*;

import com.levigo.jbig2.JBIG2ImageReader;
import com.levigo.jbig2.JBIG2ImageReaderSpi;
import com.levigo.jbig2.JBIG2ReadParam;
import com.levigo.jbig2.io.DefaultInputStreamFactory;

import java.awt.image.BufferedImage;
import java.io.*;
import javax.imageio.ImageIO;
import javax.imageio.stream.ImageInputStream;

public class JBig2Image {
    private String filepath;
    private int imageIndex;

    public JBig2Image() {
        this.filepath = "/home/blackadmin/Desktop/pdf/demo18.jbig2";
        this.imageIndex = 0;
        extractImgFromPdf();
        convertJBig2ToJpeg();
        createPDF();
    }

    private void extractImgFromPdf() {
        try {
            /////////// Extract all Images from pdf /////////////////////////

            PdfReader reader = new PdfReader("/home/blackadmin/Desktop/pdf/orig.pdf");
            PdfReaderContentParser parser = new PdfReaderContentParser(reader);
            MyImageRenderListener listener = new MyImageRenderListener("/home/blackadmin/Desktop/pdf/demo%s.%s");
            for (int i = 1; i <= reader.getNumberOfPages(); i++) {
                parser.processContent(i, listener);
            }
        } catch (IOException ex) {
            System.out.println(ex);
        }
    }

    private void convertJBig2ToJpeg() {
        InputStream inputStream = null;
        try {
            ///////// Read jbig2 image ////////////////////////////////////////
            inputStream = new FileInputStream(new File(filepath));
            DefaultInputStreamFactory disf = new DefaultInputStreamFactory();
            ImageInputStream imageInputStream = disf.getInputStream(inputStream);
            JBIG2ImageReader imageReader = new JBIG2ImageReader(new JBIG2ImageReaderSpi());
            imageReader.setInput(imageInputStream);
            JBIG2ReadParam param = imageReader.getDefaultReadParam();
            BufferedImage bufferedImage = imageReader.read(imageIndex, param);

            ////////// jbig2 to jpeg ///////////////////////////////////////////
            ImageIO.write(bufferedImage, "jpeg", new File("/home/blackadmin/Desktop/pdf/demo18.jpeg"));
        } catch (IOException ex) {
            System.out.println(ex);
        } finally {
            try {
                inputStream.close();
            } catch (IOException ex) {
                System.out.println(ex);
            }
        }
    }

    public void createPDF() {
        Document document = new Document();
        try {
            PdfWriter.getInstance(document,
                    new FileOutputStream("/home/blackadmin/Desktop/pdf/output.pdf"));
            document.open();
            PdfPTable table = new PdfPTable(1); //1 column.    
            Image image = Image.getInstance("/home/blackadmin/Desktop/pdf/demo18.jpeg");
            image.scaleToFit(800f, 600f);
            image.scaleAbsolute(800f, 600f);   // Give the size of image you want to print on pdf
            PdfPCell nestedImgCell = new PdfPCell(image);
            table.addCell(nestedImgCell);
            document.add(table);
            document.close();
            System.out.println(
                    "======== PDF Created Successfully =========");
        } catch (Exception e) {
            System.out.println(e);
        }
    }

    public static void main(String[] args) throws IOException {
        new JBig2Image();
    }
}



class MyImageRenderListener implements RenderListener {

    /**
     * The new document to which we've added a border rectangle.
     */
    protected String path = "";

    /**
     * Creates a RenderListener that will look for images.
     */
    public MyImageRenderListener(String path) {
        this.path = path;
    }

    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#beginTextBlock()
     */
    public void beginTextBlock() {
    }

    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#endTextBlock()
     */
    public void endTextBlock() {
    }

    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#renderImage(
     * com.itextpdf.text.pdf.parser.ImageRenderInfo)
     */
    public void renderImage(ImageRenderInfo renderInfo) {
        try {
            String filename;
            FileOutputStream os;
            PdfImageObject image = renderInfo.getImage();
            if (image == null) {
                return;
            }
            filename = String.format(path, renderInfo.getRef().getNumber(), image.getFileType());
            os = new FileOutputStream(filename);
            os.write(image.getImageAsBytes());
            os.flush();
            os.close();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#renderText(
     * com.itextpdf.text.pdf.parser.TextRenderInfo)
     */
    public void renderText(TextRenderInfo renderInfo) {
    }
}

参考文献:
1)提取jbig2pdf ( 提取图像 )( MyImageRenderListener )。
2)转换jbig2 ( JBIG2ImageReaderDemo )



Answer 3:

如何使用的AcrobatReader本身? 这是一个有点泥泞得到它的工作,而不是一个强大的解决方案,我猜。 但是,可能会打印出所有的它完美。 而且是免费的

关于这条路线的一些信息;

http://vineetreynolds.blogspot.nl/2005/12/silent-print-pdf-print-pdf.html http://www.codeproject.com/Questions/98586/Programmatically-print-PDF-documents HTTP:// forums.adobe.com/message/2336723



Answer 4:

你有工具的ImageMagick其处理图像并将其转换为很多格式。 我用它在几年前,所以我不能告诉你,如果JBIG2格式正确默认处理,或者如果你有安装一些插件。 你可以尝试以下具有的为J一样开始支持的格式列表JBIG2您正在寻找:

$ convert -list format | grep -i J

这实在是明显转换为PDF与工具也一样,加上gs工具又名GhostScript的 。

如果其实也没什么妨碍你要显示的图像的PNG / JPEG版本,并提供下载链接到原始文件JBIG2与自己metadatas。



Answer 5:

作为替代方案,你可以尝试这样做,服务器端:

方法1:
使用外部应用程序和打印,与其转换PDF文件到光栅图像。

方法2:
通过重新压缩JBIG2图像调整您的PDF文件:

1-解压的压缩从您的文件JBIG2图像。

与其他一些算法(JPEG,PNG等)2-重新压缩。 为了做到这一点,你可能需要使用JNI两种或外部去的Java 调用外部应用程序 。 您可以尝试jbig2dec或ImageMagic例如,如果GPL lincense适合您的需要。

3-把再压缩的图像回到你的PDF。


这种做法将意味着对那些图像,质量有所下降,但至少你将能够打印的文件。

你可以在Java中使用iText的做到这一点,有一个关于这本书的iText在行动中调整图像大小章 (样本代码)。 这个想法有提取图像,调整其大小(包括再压缩),并把它放回去。 您可以使用此作为起点。 要知道,iText的是AGPL项目,因此你不能在商业封闭源代码的应用程序免费使用它。

如果您使用的是基于Windows的服务器,你可以买得起一个商业工具,你也可以做到这一点Amyuni PDF创建或者与C#/ VB.Net或C ++( 通常的免责声明适用于这个建议 )。 你只需要去虽然类型的所有对象acObjectTypePicture并设置属性压缩到acJPegHigh ,这种方法不需要任何外部解码器JBIG2,(我可以在这里包括一些示例代码,如果你有兴趣)。

如果您使用的是小程序只打印您的PDF文件,你也可以尝试打开时生成PDF文件,显示打印对话框



文章来源: Print PDF that contains JBIG2 images