将图像添加到现有PDF文件
每个PDF页面包含资源和内容属性。资源可以是图像和表单,例如,内容由一组PDF操作符表示。每个操作符都有其名称和参数。本示例使用操作符将图像添加到PDF文件中。
要将图像添加到现有PDF文件:
-
创建一个Document对象并打开输入的PDF文档。
-
获取要添加图像的页面。
-
将图像添加到页面的getResources集合中。
-
使用操作符将图像放置在页面上:
-
使用GSave操作符保存当前图形状态。
-
使用ConcatenateMatrix操作符指定图像的位置。
-
使用 Do 操作符在页面上绘制图像。
-
最后,使用 GRestore 操作符保存更新后的图形状态。
-
保存文件。
以下代码片段展示了如何在 PDF 文档中添加图像。
package com.aspose.pdf.examples;
import java.awt.image.BufferedImage;
import java.io.ByteArrayInputStream;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileNotFoundException;
import java.io.IOException;
import javax.imageio.ImageIO;
import com.aspose.pdf.*;
import com.aspose.pdf.facades.PdfFileMend;
import com.aspose.pdf.operators.*;
public class ExampleAddImages {
private static String _dataDir = "/home/admin1/pdf-examples/Samples/";
public static void AddImageToExistingPDF() throws IOException {
// 打开一个文档
Document pdfDocument1 = new Document(_dataDir + "sample.pdf");
// 设置坐标
int lowerLeftX = 50;
int lowerLeftY = 750;
int upperRightX = 100;
int upperRightY = 800;
// 获取要添加图像的页面
Page page = pdfDocument1.getPages().get_Item(1);
// 将图像加载到流中
java.io.FileInputStream imageStream = new java.io.FileInputStream(new java.io.File(_dataDir + "logo.png"));
// 将图像添加到页面资源的 Images 集合中
page.getResources().getImages().add(imageStream);
// 使用 GSave 操作符:此操作符保存当前图形状态
page.getContents().add(new GSave());
// 创建 Rectangle 和 Matrix 对象
Rectangle rectangle = new Rectangle(lowerLeftX, lowerLeftY, upperRightX, upperRightY);
Matrix matrix = new Matrix(new double[] { rectangle.getURX() - rectangle.getLLX(), 0, 0,
rectangle.getURY() - rectangle.getLLY(), rectangle.getLLX(), rectangle.getLLY() });
// 使用 ConcatenateMatrix(连接矩阵)操作符:定义图像必须如何放置
page.getContents().add(new ConcatenateMatrix(matrix));
XImage ximage = page.getResources().getImages().get_Item(page.getResources().getImages().size());
// 使用 Do 操作符:此操作符绘制图像
page.getContents().add(new Do(ximage.getName()));
// 使用 GRestore 操作符:此操作符恢复图形状态
page.getContents().add(new GRestore());
// 保存新的 PDF
pdfDocument1.save(_dataDir + "updated_document.pdf");
// 关闭图像流
imageStream.close();
}
将 BufferedImage 中的图像添加到 PDF 中
从 Aspose.PDF for Java 9.5.0 开始,我们引入了从 BufferedImage 实例中添加图像到 PDF 文档的支持。为了支持这一需求,实现了一个方法:XImageCollection.add(BufferedImage image);
public static void AddingImageFromBufferedImageIntoPDF() throws IOException {
BufferedImage originalImage = ImageIO.read(new File("anyImage.jpg"));
Document pdfDocument = new Document();
Page page = pdfDocument.getPages().add();
page.getResources().getImages().add(originalImage);
}
您可以使用任何 InputStream,而不仅仅是 FileInputStream 对象来添加图像。因此,当使用 java.io.ByteArrayInputStream 对象时,您不需要在系统上存储任何文件:
public static void AddingImageFromBufferedImageIntoPDF2() throws IOException {
BufferedImage originalImage = ImageIO.read(new File("anyImage.jpg"));
ByteArrayOutputStream baos = new ByteArrayOutputStream();
Document pdfDocument = new Document();
ImageIO.write(originalImage, "jpg", baos);
baos.flush();
Page page = pdfDocument.getPages().get_Item(1);
page.getResources().getImages().add(new ByteArrayInputStream(baos.toByteArray()));
}
在现有 PDF 文件中添加图像(Facades)
还有一种替代的、更简单的方法可以将图像添加到 PDF 文件中。您可以使用 PdfFileMend 类的 AddImage 方法。AddImage 方法需要添加的图像、需要添加图像的页码和坐标信息。之后,使用 Close 方法保存更新后的 PDF 文件。
下面的代码片段展示了如何在现有的 PDF 文件中添加图像。
public static void AddImageInAnExistingPDFFile_Facades() {
// 打开文档
PdfFileMend mender = new PdfFileMend();
// 创建 PdfFileMend 对象以添加文本
mender.bindPdf(_dataDir + "AddImage.pdf");
// 在 PDF 文件中添加图像
mender.addImage(_dataDir + "aspose-logo.jpg", 1, 100, 600, 200, 700);
// 保存更改
mender.save(_dataDir + "AddImage_out.pdf");
// 关闭 PdfFileMend 对象
mender.close();
}
在 PDF 文档中多次引用单个图像
有时我们需要在 PDF 文档中多次使用相同的图像。添加新实例会增加生成的 PDF 文档的大小。我们添加了一个新方法 XImageCollection.add(XImage),支持将 Ximage 对象添加到 Images 集合中。此方法允许引用与原始图像相同的 PDF 对象,从而优化 PDF 文档大小。
public static void AddReferenceOfaSingleImageMultipleTimes() throws FileNotFoundException {
Rectangle imageRectangle = new Rectangle(0, 0, 30, 15);
Document document = new Document(_dataDir + "sample.pdf");
document.getPages().add();
document.getPages().add();
java.io.FileInputStream imageStream = new java.io.FileInputStream(
new java.io.File(_dataDir + "aspose-logo.png"));
XImage image = null;
for (Page page : document.getPages()) {
WatermarkAnnotation annotation = new WatermarkAnnotation(page, page.getRect());
XForm form = annotation.getAppearance().get_Item("N");
form.setBBox(page.getRect());
String name;
if (image == null) {
name = form.getResources().getImages().add(imageStream);
image = form.getResources().getImages().get_Item(name);
} else {
name = form.getResources().getImages().add(image);
}
form.getContents().add(new GSave());
form.getContents().add(new ConcatenateMatrix(
new Matrix(imageRectangle.getWidth(), 0, 0, imageRectangle.getHeight(), 0, 0)));
form.getContents().add(new Do(name));
form.getContents().add(new GRestore());
page.getAnnotations().add(annotation, false);
imageRectangle = new Rectangle(0, 0, imageRectangle.getWidth() * 1.01, imageRectangle.getHeight() * 1.01);
}
document.save(_dataDir + "output.pdf");
}
确定 PDF 中的图像是彩色还是黑白
可以对图像应用不同类型的压缩来减小它们的大小。应用于图像的压缩类型取决于源图像的颜色空间,即如果图像是彩色(RGB),则应用 JPEG2000 压缩,如果是黑白,则应应用 JBIG2/JBIG2000 压缩。因此,识别每种图像类型并使用适当的压缩类型将创建最佳/优化的输出。
PDF 文件可能包含文本、图像、图形、附件、注释等元素,如果源 PDF 文件包含图像,我们可以确定图像的颜色空间并应用适当的图像压缩来减小 PDF 文件的大小。以下代码片段显示了确定 PDF 中的图像是彩色还是黑白的步骤。
public static void CheckColors() {
Document document = new Document(_dataDir + "test4.pdf");
try {
// 迭代 PDF 文件的所有页面
for (Page page : (Iterable<Page>) document.getPages()) {
// 创建图像放置吸收器实例
ImagePlacementAbsorber abs = new ImagePlacementAbsorber();
page.accept(abs);
for (ImagePlacement ia : (Iterable<ImagePlacement>) abs.getImagePlacements()) {
/* ColorType */
int colorType = ia.getImage().getColorType();
switch (colorType) {
case ColorType.Grayscale:
System.out.println("灰度图像");
break;
case ColorType.Rgb:
System.out.println("彩色图像");
break;
}
}
}
} catch (Exception ex) {
System.out.println("读取文件时出错 = " + document.getFileName());
}
}
}