Java的PDF转图片上传oss
一、前言
做了一个pdf上传转图片并上传oss,并对图片识别需求下面主要是pdf转图片实现
选择用pdfbox去实现
二、实现
1.maven配置
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox</artifactId>
<version>2.0.28</version>
</dependency>
<dependency>
<groupId>org.apache.pdfbox</groupId>
<artifactId>pdfbox-tools</artifactId>
<version>2.0.28</version>
</dependency>
这里用的2.0.28版本
2.0 版本最新 是2.0.29
已经发布3.0版本
2.关键代码
读取pdf文件
PDDocument document = PDDocument.load(file.getInputStream(), MemoryUsageSetting.setupTempFileOnly()
允许下采样
PDFRenderer pdfRenderer = new PDFRenderer(document);
//允许下采样
pdfRenderer.setSubsamplingAllowed(true);
分页处理
// 渲染PDF页面为图像:
// page:要渲染的 PDF 页面对象
// 300:渲染的图像分辨率,通常以每英寸点数(DPI,Dots Per Inch)表示。这里将图像渲染为每英寸300个点。
// ImageType.RGB:指定图像类型为 RGB(红绿蓝)色彩模式。这表示生成的图像将包含红、绿、蓝三种颜色通道。
ByteArrayOutputStream os;
for (int page = 0; page < document.getNumberOfPages(); ++page) {
// dpi 设置你的dpi
bim = pdfRenderer.renderImageWithDPI(page, dpi, ImageType.RGB);
os = new ByteArrayOutputStream();
// 注意设置dpi 不设置默认72 dpi
ImageIOUtil.writeImage(bim , "png", os, dpi);
//上传图片到oss
aliOssUtil.uploadPdfImgToOSS(file.getOriginalFilename(), ossType, page, os);
}
注意:
1.ImageIOUtil.writeImage(bim , "png", os, dpi);
文件格式直接用jpeg会不清晰,可先转png再转jpg格式
2.dpi设置过大会导致内存溢出
3.png转jpg的demo
public static void main(String[] args) {
try {
String pdfFilePath = "path/to/your/input.pdf"; // 输入PDF文件路径
String outputDir = "path/to/your/output/directory/"; // 输出目录
PDDocument document = PDDocument.load(new File(pdfFilePath));
PDFRenderer pdfRenderer = new PDFRenderer(document);
for (int page = 0; page < document.getNumberOfPages(); ++page) {
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
String pngFileName = outputDir + "page_" + (page + 1) + ".png";
ImageIO.write(bim, "PNG", new File(pngFileName));
// 将PNG转换为JPEG
BufferedImage pngImage = ImageIO.read(new File(pngFileName));
String jpgFileName = outputDir + "page_" + (page + 1) + ".jpg";
ImageIO.write(pngImage, "JPEG", new File(jpgFileName));
}
document.close();
System.out.println("PDF转PNG和JPEG完成!");
} catch (IOException e) {
e.printStackTrace();
}
}
4.上传至oss
OSS ossClient = new OSSClientBuilder().build(endpoint, accessKeyId, accessKeySecret);
InputStream inputStream = new ByteArrayInputStream(image);
// 构建上传Object的元信息
ObjectMetadata meta = new ObjectMetadata();
meta.setContentLength(image.length);
meta.setContentType("image/jpeg");
String fileUrl = getFileUrl(ossPath, type);
try {
PutObjectResult result = ossClient.putObject(new PutObjectRequest(bucketName, fileUrl, inputStream));
}
三、 测试各pdf转图片处理各dpi(包含各种缩放处理)
|
pdf文件大小
|
100dpi
|
150dpi
|
300dpi
|
450dpi
|
600dpi
|
15页
|
448k
|
9 491ms
|
10 708ms
|
15 777ms
|
21 404ms
|
28 563ms
|
10页
|
11.08M
|
10 965ms
|
19 688ms
|
29 771ms
|
54 301ms
|
内存崩溃
|
18页
|
313k
|
10 907ms
|
12 554 ms
|
19 455ms
|
26 455ms
|
37 275ms
|
结论
pdf原始文件越大,在大于150dpi时,转图片处理,内存占用越大,越耗时间
四、遇到的问题
1.图片不清晰
- 先转成png格式再转jpg (见png转jpg的demo)
- 调高dpi大小 300是dpi配置
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
2.图片转换失败/png转jpg图片不显示背景变黄色
PNG 转换为 JPEG 图像时,背景变黄色可能是由于颜色模式和压缩参数的不同引起的。PNG 图像通常使用 RGB 颜色模式,而 JPEG 图像可以使用 YCbCr 颜色模式。这种颜色模式的变化可能会导致颜色差异,从而导致背景颜色变化。
为了解决这个问题,您可以尝试在将 PNG 转换为 JPEG 时明确指定颜色模式,以确保它与您期望的颜色一致。
BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);
3.对图片指定缩放处理
BufferedImage bim, scaledImage, rgbImage;
Graphics2D g2d;
int originalHeight, originalWidth, scaledHeight;
originalHeight = bim.getHeight();
originalWidth = bim.getWidth();
scaledHeight = (int) ((double) originalHeight / originalWidth * desiredWidth);
// desiredWidth scaledHeight 指定宽高
scaledImage = newBufferedImage(desiredWidth, scaledHeight, BufferedImage.TYPE_INT_ARGB);
g2d = scaledImage.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2d.drawImage(bim.getScaledInstance(desiredWidth, scaledHeight, Image.SCALE_SMOOTH), 0, 0, null);
g2d.dispose();
不积跬步,无以至千里;不积小流,无以成江海。