您的位置:首页 > 文旅 > 美景 > java实现,PDF转换为TIF

java实现,PDF转换为TIF

2024/10/6 11:28:44 来源:https://blog.csdn.net/sxzlc/article/details/141872725  浏览:    关键词:java实现,PDF转换为TIF

目录

■JDK版本

■java代码・实现效果

■POM引用

■之前TIF相关的问题(两张TIF合并)

■对于成果物TIF,需要考虑的点

■问题

■问题1:无法生成TIF,已解决

■问题2:生成的TIF过大,已解决

解决方法1:使用LZW方式压缩

解决方法2:让图片位深度为黑白(binary),并且使用CCITT方式压缩

■相关工具

SVF

foxit

■相关知识

ImageIO.write 的结果是 false 的原因

转换时报错 type 4 gsub lookup table is not supported

DPI是什么

一英寸 是多少厘米

图片的 位深度

■功能扩展

转换为TIF时,能否在TIF中的某个坐标点,再追加什么信息

4页的PDF,取出一部分,生成3页的PDF

印章(在右上角)

印章(改进版)(坐标自己定义)


=================

■JDK版本

1.8

■java代码・实现效果

package com.sxz.study.pdf;import java.awt.image.BufferedImage;
import java.io.File;import javax.imageio.ImageIO;import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;public class TestPDFToTIF {public static void main(String[] args) {try {// Load the PDF documentPDDocument document = PDDocument.load(new File("E:\\Users\\sxz\\Desktop\\PDF\\Test.pdf"));// Create a PDF rendererPDFRenderer pdfRenderer = new PDFRenderer(document);// Iterate over each page in the PDF documentfor (int pageNumber = 0; pageNumber < document.getNumberOfPages(); pageNumber++) {// Render the PDF page to a BufferedImage// BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, 300, ImageType.RGB);BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, 200, ImageType.GRAY);// Save the BufferedImage as a TIF fileboolean flg = ImageIO.write(image, "tif", new File("E:\\Users\\sxz\\Desktop\\PDF\\output_" + (pageNumber + 1) + ".tif"));System.out.println(flg);}// Close the PDF documentdocument.close();System.out.println("PDF converted to TIF successfully");} catch (Exception e) {e.printStackTrace();}}}

===

====

=====

■POM引用

		<dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox</artifactId><version>2.0.24</version> <!-- 可以根据需要选择最新版本 --></dependency><dependency><groupId>org.apache.pdfbox</groupId><artifactId>pdfbox-tools</artifactId><version>2.0.24</version> <!-- 可以根据需要选择最新版本 --></dependency><dependency><groupId>org.apache.pdfbox</groupId><artifactId>fontbox</artifactId><version>2.0.24</version> <!-- 可以根据需要选择最新版本 --></dependency><dependency><groupId>com.github.jai-imageio</groupId><artifactId>jai-imageio-core</artifactId><version>1.4.0</version></dependency>

====

====

■之前TIF相关的问题(两张TIF合并)

TIF合并Java代码_jai-codec-CSDN博客

====

■对于成果物TIF,需要考虑的点

不是单纯生成TIF就可以了,还要考虑以下问题

①白黒閾値
②解像度 (分辨率) (DPI) ⇒ 一般设置为200
③圧縮方式  -----CCITT T.4
④位深度 1,8,24,32 // 代码  ⇒  ImageType.BINARY
⑤XXXX高 XXXX幅  ⇒ 影响坐标位置
⑥ファイルのサイズ  XXXXKB
⑦分辨率单位  // TODO 代码如何指定
⑧是否还要在生成的TIF上写入什么(番号),或者重新写入什么(比如页码 1/4 ⇒1/5)// 已经实现
⑨4页的PDF,出力1,2,4页 // 已经实现
⑩処理スピード(处理速度)

⑪事前確認 上流SystemのInput (PDF)

      下流Systemへ連携のTIF

====

====

■问题

■问题1:无法生成TIF,已解决

问题:结果全部为false。

解决:

   方法1:pom中添加如下引用

		<dependency><groupId>com.github.jai-imageio</groupId><artifactId>jai-imageio-core</artifactId><version>1.4.0</version></dependency>

   方法2:使用jdk9

====

■问题2:生成的TIF过大,已解决

====

我原本文件才0.3M,生成的TIF有3M的大小。。。。

====方法2解决后的效果

===

解决方法1:使用LZW方式压缩

package com.sxz.study.pdf;import java.awt.image.BufferedImage;
import java.io.File;import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;public class TestPDFToTIFCompress {public static void main(String[] args) {try {// Load the PDF documentPDDocument document = PDDocument.load(new File("C:\\test\\PDF\\Test.pdf"));// Create a PDF rendererPDFRenderer pdfRenderer = new PDFRenderer(document);// Iterate over each page in the PDF documentfor (int pageNumber = 0; pageNumber < document.getNumberOfPages(); pageNumber++) {// Render the PDF page to a BufferedImage// BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, 300,// ImageType.RGB);BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, 200, ImageType.GRAY);ImageWriter writer = ImageIO.getImageWritersByFormatName("tiff").next();ImageWriteParam writeParam = writer.getDefaultWriteParam();writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);writeParam.setCompressionType("LZW");// 创建输出文件流FileImageOutputStream output = new FileImageOutputStream(new File("C:\\test\\PDF\\output_" + (pageNumber + 1) + ".tif"));writer.setOutput(output);// 写入压缩后的TIF图像writer.write(null, new IIOImage(image, null, null), writeParam);// 关闭输出流output.close();}// Close the PDF documentdocument.close();System.out.println("PDF converted to TIF successfully");} catch (Exception e) {e.printStackTrace();}}
}

===

ImageType.GRAY

位深度是 8

====

解决方法2:让图片位深度为黑白(binary),并且使用CCITT方式压缩

===

ImageType.GRAY 时,代码运行会报错

Caused by: javax.imageio.IIOException: Bits per sample must be 1 for T4 compression!

==

package com.sxz.study.pdf;import java.awt.image.BufferedImage;
import java.io.File;import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;public class TestPDFToTIFCompress {public static void main(String[] args) {try {// Load the PDF documentPDDocument document = PDDocument.load(new File("C:\\test\\PDF\\Test.pdf"));// Create a PDF rendererPDFRenderer pdfRenderer = new PDFRenderer(document);// Iterate over each page in the PDF documentfor (int pageNumber = 0; pageNumber < document.getNumberOfPages(); pageNumber++) {// Render the PDF page to a BufferedImage// BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, 300,// ImageType.RGB);BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, 200, ImageType.GRAY);ImageWriter writer = ImageIO.getImageWritersByFormatName("tiff").next();ImageWriteParam writeParam = writer.getDefaultWriteParam();writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);writeParam.setCompressionType("LZW");// 创建输出文件流FileImageOutputStream output = new FileImageOutputStream(new File("C:\\test\\PDF\\output_" + (pageNumber + 1) + ".tif"));writer.setOutput(output);// 写入压缩后的TIF图像writer.write(null, new IIOImage(image, null, null), writeParam);// 关闭输出流output.close();}// Close the PDF documentdocument.close();System.out.println("PDF converted to TIF successfully");} catch (Exception e) {e.printStackTrace();}}
}

===

===

■相关工具

SVF

====4141

1.1. SVF Connect for Java APIの機能概要 (wingarc.com)

==== ウイングアーク1stコーポレートサイト

会社概要 | ウイングアーク1stコーポレートサイト (wingarc.com)

===

foxit

xxx

===

■相关知识

ImageIO.write 的结果是 false 的原因

如果ImageIO.write方法返回false,可能有几种原因导致无法成功将BufferedImage写入TIF文件。以下是一些常见原因和可能解决方法:

  1. 缺少合适的ImageWriter:ImageIO在写入图像时需要能够识别和处理指定格式(这里是TIF)的ImageWriter。可能需要确保已经安装了支持TIF格式的插件。通常,这些插件会提供相应的ImageWriter类。

    解决方法:可以尝试安装支持TIF格式的插件,例如JAI Image I/O Tools。您可以在Maven中添加以下依赖项:

		<dependency><groupId>com.github.jai-imageio</groupId><artifactId>jai-imageio-core</artifactId><version>1.4.0</version></dependency>

转换时报错 type 4 gsub lookup table is not supported

报错"Type 4 gsub lookup table is not supported"通常是由于字体文件中的某种字符映射表(lookup table)不受支持而导致的。字形字体(OpenType字体)中的子集(subset)可能包含一些复杂的字符映射表,而某些库可能无法正确解析或处理这些表。您可以尝试以下解决方法:

  1. 使用全字形字体(Full OpenType Font):如果可能,尝试使用未经子集化的完整字形字体,而不是子集化的字体。全字形字体包含完整的字符集和字符映射表,可能更容易被解析和处理。

  2. 更新软件版本:检查您使用的库或工具是否存在更新版本,有时新版本可能会修复一些已知的问题。

  3. 选择其他字体或库:尝试使用其他字体或处理字体的库来查看能否解决该问题。不同的库可能有不同的实现方式,可能支持更多的字符映射表类型。

  4. 解析错误:检查报错代码所在的地方,看看是否可以在代码中进行特定的处理,例如跳过不支持的部分或者采取其他替代方案。

DPI是什么

DPI代表“每英寸点数”(Dots Per Inch),是衡量输出设备打印或显示分辨率的度量单位。它表示在每英寸内打印机或显示器能够输出多少个像素点。在打印领域中,DPI表示每英寸的打印点密度,越高的DPI通常意味着更高的打印质量和更细致的图像。在显示器领域中,DPI用来描述屏幕的像素密度,影响屏幕展示的清晰度和细节。

例如,如果一台打印机的DPI为600,则表示在打印一英寸长度的纸张上,这台打印机可以输出600个点(像素),从而打印出高分辨率的图像或文档。

在设计和图像处理中,DPI也很重要,因为它决定了图像在输出时的清晰度和质量。对于印刷品、海报、名片等需要高质量印刷的材料,通常需要使用高DPI的图像以确保印刷效果。

总之,DPI是衡量输出设备分辨率的重要指标,对于打印、显示和图像处理等领域都有着重要作用。

一英寸 是多少厘米

一英寸等于2.54厘米。这是国际上普遍接受的英制和公制长度单位之间的换算关系。根据这个换算关系,1英寸等于2.54厘米。

图片的 位深度

图片的位深度是指图像中每个像素的颜色值所占用的位数。位深度越高,可以表示的颜色范围就越大,图像也会更加细致。常见的位深度有:

1位深度:每个像素只有两种颜色,通常用于黑白图像或简单的图标。 ImageType.BINARY

8位深度:每个像素有256种颜色,通常用于网页图像或简单的照片。  ImageType.GRAY

24位深度:每个像素有约1677万种颜色,通常用于高质量的照片。

32位深度:除了颜色信息外,还包含Alpha通道信息,用于透明度处理。

不同的位深度会影响图像的颜色表现和细节展现,选择合适的位深度能够更好地展现图片的效果。

==

■功能扩展

转换为TIF时,能否在TIF中的某个坐标点,再追加什么信息

==

要在TIF图像的某个坐标点追加额外信息,你可以使用Java开发中的图像处理库,如ImageMagick或Java自带的图像处理库,来在生成的TIF图像上绘制文本或其他图形。

下面是一个示例代码,演示如何使用Java的Graphics2D来在TIF图像的指定坐标绘制文本信息:

例子代码

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.tools.imageio.ImageIOUtil;import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;public class PdfToTifConverter {public static void main(String[] args) {try {File pdfFile = new File("input.pdf");PDDocument document = PDDocument.load(pdfFile);PDFRenderer pdfRenderer = new PDFRenderer(document);for (int page = 0; page < document.getNumberOfPages(); ++page) {BufferedImage bim = pdfRenderer.renderImageWithDPI(page, 300, ImageType.RGB);// 在图像上绘制文本信息Graphics2D g = bim.createGraphics();g.setColor(Color.RED);g.setFont(new Font("Arial", Font.PLAIN, 20));g.drawString("Additional Info", 100, 100);g.dispose();ImageIOUtil.writeImage(bim, "output_" + page + ".tif", 300);}document.close();} catch (Exception e) {e.printStackTrace();}}
}

===

完整代码

package com.sxz.study.pdf;import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;public class TestPdfToTifComPressCCITTWithInfo {public static void main(String[] args) {try {// Load the PDF documentPDDocument document = PDDocument.load(new File("C:\\test\\PDF\\0830.pdf"));// Create a PDF rendererPDFRenderer pdfRenderer = new PDFRenderer(document);// Iterate over each page in the PDF documentfor (int pageNumber = 0; pageNumber < document.getNumberOfPages(); pageNumber++) {// Render the PDF page to a BufferedImage// BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, 300,// ImageType.RGB);BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, 200, ImageType.BINARY);// 在图像上绘制文本信息// 抹去之前的信息Graphics2D g2 = image.createGraphics();g2.setColor(Color.white);g2.setFont(new Font("Arial", Font.PLAIN, 80));g2.drawString("■■■■■■■■■■■■■■■■■■■■■■■■", 400, 400);g2.dispose();Graphics2D g3 = image.createGraphics();g3.setColor(Color.white);g3.setFont(new Font("Arial", Font.PLAIN, 80));g3.drawString("■■■■■■■■■■■■■■■■■■■■■■■■", 405, 400);g3.dispose();Graphics2D g4 = image.createGraphics();g4.setColor(Color.white);g4.setFont(new Font("Arial", Font.PLAIN, 80));g4.drawString("■■■■■■■■■■■■■■■■■■■■■■■■", 410, 400);g4.dispose();Graphics2D g5 = image.createGraphics();g5.setColor(Color.white);g5.setFont(new Font("Arial", Font.PLAIN, 80));g5.drawString("■■■■■■■■■■■■■■■■■■■■■■■■", 415, 400);g5.dispose();// 写上想要的信息Graphics2D g = image.createGraphics();g.setColor(Color.BLACK);g.setFont(new Font("Arial", Font.PLAIN, 20));g.drawString("66666666666666666666666666666666666666666", 410, 400);g.dispose();ImageWriter writer = ImageIO.getImageWritersByFormatName("tiff").next();ImageWriteParam writeParam = writer.getDefaultWriteParam();writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);writeParam.setCompressionType("CCITT T.4");//writeParam.setCompressionQuality(1.0f);// 创建输出文件流FileImageOutputStream output = new FileImageOutputStream(new File("C:\\test\\PDF\\output_" + (pageNumber + 1) + ".tif"));writer.setOutput(output);// 写入压缩后的TIF图像writer.write(null, new IIOImage(image, null, null), writeParam);// 关闭输出流output.close();}// Close the PDF documentdocument.close();System.out.println("PDF converted to TIF successfully");} catch (Exception e) {e.printStackTrace();}}
}

===

===

4页的PDF,取出一部分,生成3页的PDF

==

package com.sxz.study.pdf;import java.io.File;
import java.io.IOException;import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;public class TestPdfAllToPDF {// java代码实现,iput1:1到页的PDF,output :1,2,4页的PDFpublic static void main(String[] args) {try {File inputFile = new File("C:\\test\\PDF\\input.pdf");PDDocument document = PDDocument.load(inputFile);PDDocument outputDocument = new PDDocument();int[] selectedPages = {0, 1, 3}; // 选择要提取的页面,索引从0开始for (int pageNumber : selectedPages) {if (pageNumber < document.getNumberOfPages()) {PDPage page = document.getPage(pageNumber);outputDocument.addPage(page);} else {System.out.println("Invalid page number: " + (pageNumber + 1));}}outputDocument.save("C:\\test\\PDF\\output.pdf");outputDocument.close();document.close();System.out.println("Selected pages extracted successfully.");} catch (IOException e) {e.printStackTrace();}}
}

xxx

===

印章(在右上角)

部分代码(参考)

public static void main(String[] args) throws IOException {int imageSize = 150;BufferedImage bufferedImage = new BufferedImage(imageSize, imageSize, BufferedImage.TYPE_INT_ARGB);Graphics2D g2d = bufferedImage.createGraphics();// 防止出现锯齿g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);g2d.setComposite(AlphaComposite.Src);g2d.setColor(Color.red);g2d.setStroke(new BasicStroke(3));// 绘画起点xy坐标并非圆心坐标g2d.drawOval(2, 2, imageSize - 4, imageSize - 4);// 绘画五角星int r = 20;int centerPoint = imageSize / 2;Map<String, List<Integer>> pointersMap = new HashMap<>();// 五角星6点坐标 O为圆心点pointersMap.put("O", Arrays.asList(centerPoint, centerPoint));pointersMap.put("A", Arrays.asList(centerPoint, centerPoint - r));pointersMap.put("B", Arrays.asList((int)(centerPoint + Math.sin(0.4 * Math.PI) * r), (int)(centerPoint - Math.cos(0.4 * Math.PI) * r)));pointersMap.put("C", Arrays.asList((int)(centerPoint + Math.sin(0.2 * Math.PI) * r), (int)(centerPoint + Math.cos(0.2 * Math.PI) * r)));pointersMap.put("D", Arrays.asList((int)(centerPoint - Math.sin(0.2 * Math.PI) * r), (int)(centerPoint + Math.cos(0.2 * Math.PI) * r)));pointersMap.put("E", Arrays.asList((int)(centerPoint - Math.sin(0.4 * Math.PI) * r), (int)(centerPoint - Math.cos(0.4 * Math.PI) * r)));// 6点组合绘画图像List<String> pointerComposes = Arrays.asList("A,D,O,C", "B,E,O,D", "C,A,O,E", "D,A,O,B", "E,C,O,B");// 查找绘画点进行绘画for (String pointerCompose : pointerComposes) {String[] pointerKeys = pointerCompose.split(",");Polygon polygon = new Polygon();for (String pointerKey : pointerKeys) {polygon.addPoint(pointersMap.get(pointerKey).get(0), pointersMap.get(pointerKey).get(1));}g2d.fillPolygon(polygon);}int whiteSpace = 75;double padding = 1.5;String companyName = "XXXXXXXXXXXXXXXXXX";// 根据名称长度 动态设置字体大小 防止文字过多发生文字碰撞int fontSize = (60 - companyName.length()) / 3;// 平移画布使环形文字在圆圈内g2d.translate(centerPoint - fontSize / 2, 0);// 文字开始位置 大概在左下角g2d.rotate(((double) whiteSpace / 360) * Math.PI + Math.PI, fontSize / 2, centerPoint);Font font = new Font("FangSong_GB2312", Font.ROMAN_BASELINE, fontSize);g2d.setFont(font);// 在文字开始位置 第二个字符开始进行按计算角度进行旋转 从而生成环形文字double rotateAngle = (double) (360 - whiteSpace) * Math.PI / (180 * (companyName.length() - 1));for (int i = 0; i < companyName.toCharArray().length; i++) {if (i != 0) {g2d.rotate(rotateAngle, fontSize/2, centerPoint);}g2d.drawString(String.valueOf(companyName.toCharArray()[i]), 0, (int) (fontSize * padding));}ByteArrayOutputStream baos = new ByteArrayOutputStream();ImageIO.write(bufferedImage, "png", baos);String path = String.format("D:/data/seal_image/seal.%s.png",DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS").format(LocalDateTime.now()));File file = new File(path);FileOutputStream fileOutputStream = new FileOutputStream(file);fileOutputStream.write(baos.toByteArray());baos.close();fileOutputStream.close();}

全部代码

package com.sxz.study.pdf;import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.time.LocalDateTime;
import java.time.format.DateTimeFormatter;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;public class TestPDFToTIFCompressLZWWithStamp {public static void main(String[] args) {try {// Load the PDF documentPDDocument document = PDDocument.load(new File("C:\\test\\PDF\\Test.pdf"));// Create a PDF rendererPDFRenderer pdfRenderer = new PDFRenderer(document);// Iterate over each page in the PDF documentfor (int pageNumber = 0; pageNumber < document.getNumberOfPages(); pageNumber++) {// Render the PDF page to a BufferedImage// BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, 300,// ImageType.RGB);BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, 200, ImageType.GRAY);// 在图像上绘制  印章Graphics2D g2d = image.createGraphics();int imageSize = 150;// 防止出现锯齿g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);g2d.setComposite(AlphaComposite.Src);g2d.setColor(Color.red);g2d.setStroke(new BasicStroke(3));// 绘画起点xy坐标并非圆心坐标g2d.drawOval(2, 2, imageSize - 4, imageSize - 4);// 绘画五角星int r = 20;int centerPoint = imageSize / 2;Map<String, List<Integer>> pointersMap = new HashMap<>();// 五角星6点坐标 O为圆心点pointersMap.put("O", Arrays.asList(centerPoint, centerPoint));pointersMap.put("A", Arrays.asList(centerPoint, centerPoint - r));pointersMap.put("B", Arrays.asList((int)(centerPoint + Math.sin(0.4 * Math.PI) * r), (int)(centerPoint - Math.cos(0.4 * Math.PI) * r)));pointersMap.put("C", Arrays.asList((int)(centerPoint + Math.sin(0.2 * Math.PI) * r), (int)(centerPoint + Math.cos(0.2 * Math.PI) * r)));pointersMap.put("D", Arrays.asList((int)(centerPoint - Math.sin(0.2 * Math.PI) * r), (int)(centerPoint + Math.cos(0.2 * Math.PI) * r)));pointersMap.put("E", Arrays.asList((int)(centerPoint - Math.sin(0.4 * Math.PI) * r), (int)(centerPoint - Math.cos(0.4 * Math.PI) * r)));// 6点组合绘画图像List<String> pointerComposes = Arrays.asList("A,D,O,C", "B,E,O,D", "C,A,O,E", "D,A,O,B", "E,C,O,B");// 查找绘画点进行绘画for (String pointerCompose : pointerComposes) {String[] pointerKeys = pointerCompose.split(",");Polygon polygon = new Polygon();for (String pointerKey : pointerKeys) {polygon.addPoint(pointersMap.get(pointerKey).get(0), pointersMap.get(pointerKey).get(1));}g2d.fillPolygon(polygon);}int whiteSpace = 75;double padding = 1.5;String companyName = "中国足球七比零";// 根据名称长度 动态设置字体大小 防止文字过多发生文字碰撞int fontSize = (60 - companyName.length()) / 3;// 平移画布使环形文字在圆圈内g2d.translate(centerPoint - fontSize / 2, 0);// 文字开始位置 大概在左下角g2d.rotate(((double) whiteSpace / 360) * Math.PI + Math.PI, fontSize / 2, centerPoint);Font font = new Font("FangSong_GB2312", Font.ROMAN_BASELINE, fontSize);g2d.setFont(font);// 在文字开始位置 第二个字符开始进行按计算角度进行旋转 从而生成环形文字double rotateAngle = (double) (360 - whiteSpace) * Math.PI / (180 * (companyName.length() - 1));for (int i = 0; i < companyName.toCharArray().length; i++) {if (i != 0) {g2d.rotate(rotateAngle, fontSize/2, centerPoint);}g2d.drawString(String.valueOf(companyName.toCharArray()[i]), 0, (int) (fontSize * padding));}ByteArrayOutputStream baos = new ByteArrayOutputStream();g2d.setColor(Color.BLACK);g2d.dispose();//                String path = String.format("D:/data/seal_image/seal.%s.png",
//                    DateTimeFormatter.ofPattern("yyyyMMddHHmmssSSS").format(
//                        LocalDateTime.now()));
//                File file = new File(path);
//                FileOutputStream fileOutputStream = new FileOutputStream(file);
//                fileOutputStream.write(baos.toByteArray());
//                baos.close();
//                fileOutputStream.close();// ----endImageWriter writer = ImageIO.getImageWritersByFormatName("tiff").next();ImageWriteParam writeParam = writer.getDefaultWriteParam();writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);writeParam.setCompressionType("LZW");//writeParam.setCompressionQuality(1.0f);// 创建输出文件流FileImageOutputStream output = new FileImageOutputStream(new File("C:\\test\\PDF\\output_" + (pageNumber + 1) + ".tif"));writer.setOutput(output);// 写入压缩后的TIF图像writer.write(null, new IIOImage(image, null, null), writeParam);// 关闭输出流output.close();}// Close the PDF documentdocument.close();System.out.println("PDF converted to TIF successfully");} catch (Exception e) {e.printStackTrace();}}
}

===

===

印章(改进版)(坐标自己定义)

初版

package com.sxz.study.pdf;import java.awt.AlphaComposite;
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Polygon;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.util.Arrays;
import java.util.HashMap;
import java.util.List;
import java.util.Map;import javax.imageio.IIOImage;
import javax.imageio.ImageIO;
import javax.imageio.ImageWriteParam;
import javax.imageio.ImageWriter;
import javax.imageio.stream.FileImageOutputStream;import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;public class TestPDFToTIFCompressLZWWithStampXY {public static void main(String[] args) {try {// Load the PDF documentPDDocument document = PDDocument.load(new File("C:\\test\\PDF\\Test.pdf"));// Create a PDF rendererPDFRenderer pdfRenderer = new PDFRenderer(document);// Iterate over each page in the PDF documentfor (int pageNumber = 0; pageNumber < document.getNumberOfPages(); pageNumber++) {// Render the PDF page to a BufferedImage// BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, 300,// ImageType.RGB);BufferedImage image = pdfRenderer.renderImageWithDPI(pageNumber, 200, ImageType.GRAY);// 打印图章printStamp(image, 0, 0);ImageWriter writer = ImageIO.getImageWritersByFormatName("tiff").next();ImageWriteParam writeParam = writer.getDefaultWriteParam();writeParam.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);writeParam.setCompressionType("LZW");//writeParam.setCompressionQuality(1.0f);// 创建输出文件流FileImageOutputStream output = new FileImageOutputStream(new File("C:\\test\\PDF\\output_" + (pageNumber + 1) + ".tif"));writer.setOutput(output);// 写入压缩后的TIF图像writer.write(null, new IIOImage(image, null, null), writeParam);// 关闭输出流output.close();}// Close the PDF documentdocument.close();System.out.println("PDF converted to TIF successfully");} catch (Exception e) {e.printStackTrace();}}public static void printStamp(BufferedImage image, int xxx ,int yyy){// 在图像上绘制  印章Graphics2D g2d = image.createGraphics();int imageSize = 150;// 防止出现锯齿g2d.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);g2d.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_SPEED);g2d.setComposite(AlphaComposite.Src);g2d.setColor(Color.red);g2d.setStroke(new BasicStroke(3));// 绘画起点xy坐标并非圆心坐标g2d.drawOval(2, 2, imageSize - 4, imageSize - 4);// 绘画五角星int r = 20;int centerPoint = imageSize / 2;Map<String, List<Integer>> pointersMap = new HashMap<>();// 五角星6点坐标 O为圆心点pointersMap.put("O", Arrays.asList(centerPoint, centerPoint));pointersMap.put("A", Arrays.asList(centerPoint, centerPoint - r));pointersMap.put("B", Arrays.asList((int)(centerPoint + Math.sin(0.4 * Math.PI) * r), (int)(centerPoint - Math.cos(0.4 * Math.PI) * r)));pointersMap.put("C", Arrays.asList((int)(centerPoint + Math.sin(0.2 * Math.PI) * r), (int)(centerPoint + Math.cos(0.2 * Math.PI) * r)));pointersMap.put("D", Arrays.asList((int)(centerPoint - Math.sin(0.2 * Math.PI) * r), (int)(centerPoint + Math.cos(0.2 * Math.PI) * r)));pointersMap.put("E", Arrays.asList((int)(centerPoint - Math.sin(0.4 * Math.PI) * r), (int)(centerPoint - Math.cos(0.4 * Math.PI) * r)));// 6点组合绘画图像List<String> pointerComposes = Arrays.asList("A,D,O,C", "B,E,O,D", "C,A,O,E", "D,A,O,B", "E,C,O,B");// 查找绘画点进行绘画for (String pointerCompose : pointerComposes) {String[] pointerKeys = pointerCompose.split(",");Polygon polygon = new Polygon();for (String pointerKey : pointerKeys) {polygon.addPoint(pointersMap.get(pointerKey).get(0), pointersMap.get(pointerKey).get(1));}g2d.fillPolygon(polygon);}int whiteSpace = 75;double padding = 1.5;String companyName = "中国足球七比零";// 根据名称长度 动态设置字体大小 防止文字过多发生文字碰撞int fontSize = (60 - companyName.length()) / 3;// 平移画布使环形文字在圆圈内g2d.translate(centerPoint - fontSize / 2, 0);// 文字开始位置 大概在左下角g2d.rotate(((double) whiteSpace / 360) * Math.PI + Math.PI, fontSize / 2, centerPoint);Font font = new Font("FangSong_GB2312", Font.ROMAN_BASELINE, fontSize);g2d.setFont(font);// 在文字开始位置 第二个字符开始进行按计算角度进行旋转 从而生成环形文字double rotateAngle = (double) (360 - whiteSpace) * Math.PI / (180 * (companyName.length() - 1));for (int i = 0; i < companyName.toCharArray().length; i++) {if (i != 0) {g2d.rotate(rotateAngle, fontSize/2, centerPoint);}g2d.drawString(String.valueOf(companyName.toCharArray()[i]), 0, (int) (fontSize * padding));}g2d.setColor(Color.BLACK);g2d.dispose();}}

定义坐标号

====

版权声明:

本网仅为发布的内容提供存储空间,不对发表、转载的内容提供任何形式的保证。凡本网注明“来源:XXX网络”的作品,均转载自其它媒体,著作权归作者所有,商业转载请联系作者获得授权,非商业转载请注明出处。

我们尊重并感谢每一位作者,均已注明文章来源和作者。如因作品内容、版权或其它问题,请及时与我们联系,联系邮箱:809451989@qq.com,投稿邮箱:809451989@qq.com