目录
■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
印章(在右上角)
印章(改进版)(坐标自己定义)
PDF生成jpg图片
代码比较(印章 和 JPG),代码原理
介绍一下 java中的Graphics2D 类
印章代码参照
=================
■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文件。以下是一些常见原因和可能解决方法:
缺少合适的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)可能包含一些复杂的字符映射表,而某些库可能无法正确解析或处理这些表。您可以尝试以下解决方法:
使用全字形字体(Full OpenType Font):如果可能,尝试使用未经子集化的完整字形字体,而不是子集化的字体。全字形字体包含完整的字符集和字符映射表,可能更容易被解析和处理。
更新软件版本:检查您使用的库或工具是否存在更新版本,有时新版本可能会修复一些已知的问题。
选择其他字体或库:尝试使用其他字体或处理字体的库来查看能否解决该问题。不同的库可能有不同的实现方式,可能支持更多的字符映射表类型。
解析错误:检查报错代码所在的地方,看看是否可以在代码中进行特定的处理,例如跳过不支持的部分或者采取其他替代方案。
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();}}
}
===
===
印章(改进版)(坐标自己定义)
初版 (修改前 Base)
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();}}
定义坐标位置
效果
代碼(修改后可用代碼)
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, 600, 500);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 + xxx, 2 + yyy, 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) + xxx, pointersMap.get(pointerKey).get(1) + yyy);}g2d.fillPolygon(polygon);}int whiteSpace = 75;double padding = 1.5;String companyName = "中国足球七比零";// 根据名称长度 动态设置字体大小 防止文字过多发生文字碰撞int fontSize = (60 - companyName.length()) / 3;// 平移画布使环形文字在圆圈内g2d.translate((centerPoint - fontSize / 2) + xxx, 0 + yyy);// 文字开始位置 大概在左下角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();}}
====
PDF生成jpg图片
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 TestPDFToJpg {public static void main(String[] args) {try {// Load the PDF documentPDDocument document = PDDocument.load(new File("C:\\test\\PDF\\Java.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.RGB);ImageWriter writer = ImageIO.getImageWritersByFormatName("jpg").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) + ".jpg"));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();}}
}
==
===
代码比较(印章 和 JPG),代码原理
==
介绍一下 java中的Graphics2D 类
Graphics2D
类是Java 2D图形库中的一个关键类,它扩展了Graphics
类,提供了更强大和灵活的绘图功能。Graphics2D
类允许开发人员在屏幕上绘制2D图形,包括线条、形状、文本和图像等。以下是Graphics2D
类的一些重要特性和用途:
继承自
Graphics
类:Graphics2D
类继承自Graphics
类,因此可以使用所有Graphics
类中定义的方法,并添加了更多的高级图形绘制方法。支持图形的平移、旋转、缩放等操作:通过
Graphics2D
类提供的方法,可以轻松地对绘制的2D图形进行平移、旋转、缩放等变换操作,从而实现更灵活的绘图效果。支持抗锯齿渲染:
Graphics2D
类可以实现图形的抗锯齿渲染,使绘制出来的图形边缘更加平滑,提高图形绘制的质量。绘制简单图形:通过
drawLine()
、drawRect()
、drawOval()
等方法,可以在画布上绘制直线、矩形、椭圆等简单形状。绘制复杂图形:
Graphics2D
类提供了一系列高级绘图方法,使开发人员可以创建和绘制复杂的图形,如贝塞尔曲线、路径、复杂的多边形等。绘制文本和图像:除了绘制图形外,
Graphics2D
类还提供了绘制文本和图像的方法,可以在图形上添加文字或插入图片。总的来说,
Graphics2D
类是Java中2D图形绘制的一个核心类,提供了丰富的功能和方法,使开发人员可以实现各种各样的绘图效果。如果您需要在Java应用程序中进行2D图形绘制和渲染操作,Graphics2D
类是一个非常有用和强大的工具。
==
印章代码参照
java圆形印章生成_java.awt 画印章-CSDN博客
====