请给我建议一些库,这将有助于我打印包含JBIG2编码的图像的PDF文件。 PDFRenderer
, PDFBox
不帮我。 这些库可以打印简单的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
错误跟踪器: 在这里和这里 。
有通过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);
安德鲁。
通过在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)提取jbig2
从pdf
( 提取图像 )( MyImageRenderListener )。
2)转换jbig2
( JBIG2ImageReaderDemo )
如何使用的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
你有工具的ImageMagick其处理图像并将其转换为很多格式。 我用它在几年前,所以我不能告诉你,如果JBIG2格式正确默认处理,或者如果你有安装一些插件。 你可以尝试以下具有的为J一样开始支持的格式列表JBIG2
您正在寻找:
$ convert -list format | grep -i J
这实在是明显转换为PDF与工具也一样,加上gs
工具又名GhostScript的 。
如果其实也没什么妨碍你要显示的图像的PNG / JPEG版本,并提供下载链接到原始文件JBIG2与自己metadatas。
作为替代方案,你可以尝试这样做,服务器端:
方法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文件,显示打印对话框