目录
[解决方法1:使用LZW方式压缩 (质量高)](#解决方法1:使用LZW方式压缩 (质量高))
[解决方法2:让图片位深度为黑白(binary),并且使用CCITT方式压缩 (质量低)](#解决方法2:让图片位深度为黑白(binary),并且使用CCITT方式压缩 (质量低))
[ImageIO.write 的结果是 false 的原因](#ImageIO.write 的结果是 false 的原因)
[转换时报错 type 4 gsub lookup table is not supported](#转换时报错 type 4 gsub lookup table is not supported)
[一英寸 是多少厘米](#一英寸 是多少厘米)
[图片的 位深度](#图片的 位深度)
[代码比较(印章 和 JPG),代码原理](#代码比较(印章 和 JPG),代码原理)
[介绍一下 java中的Graphics2D 类](#介绍一下 java中的Graphics2D 类)
=================
■JDK版本
1.8
■java代码・实现效果
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 document
PDDocument document = PDDocument.load(new File("E:\\Users\\sxz\\Desktop\\PDF\\Test.pdf"));
// Create a PDF renderer
PDFRenderer pdfRenderer = new PDFRenderer(document);
// Iterate over each page in the PDF document
for (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 file
boolean flg = ImageIO.write(image, "tif", new File("E:\\Users\\sxz\\Desktop\\PDF\\output_" + (pageNumber + 1) + ".tif"));
System.out.println(flg);
}
// Close the PDF document
document.close();
System.out.println("PDF converted to TIF successfully");
} catch (Exception e) {
e.printStackTrace();
}
}
}
===
====
=====
■POM引用
XML
<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,需要考虑的点
不是单纯生成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中添加如下引用
XML
<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方式压缩 (质量高)
java
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 document
PDDocument document = PDDocument.load(new File("C:\\test\\PDF\\Test.pdf"));
// Create a PDF renderer
PDFRenderer pdfRenderer = new PDFRenderer(document);
// Iterate over each page in the PDF document
for (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 document
document.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!
==
java
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 document
PDDocument document = PDDocument.load(new File("C:\\test\\PDF\\Test.pdf"));
// Create a PDF renderer
PDFRenderer pdfRenderer = new PDFRenderer(document);
// Iterate over each page in the PDF document
for (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 document
document.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中添加以下依赖项:
XML
<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图像的指定坐标绘制文本信息:
例子代码
java
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();
}
}
}
===
完整代码
java
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 document
PDDocument document = PDDocument.load(new File("C:\\test\\PDF\\0830.pdf"));
// Create a PDF renderer
PDFRenderer pdfRenderer = new PDFRenderer(document);
// Iterate over each page in the PDF document
for (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 document
document.close();
System.out.println("PDF converted to TIF successfully");
} catch (Exception e) {
e.printStackTrace();
}
}
}
===
===
4页的PDF,取出一部分,生成3页的PDF
==
java
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页的PDF
public 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
===
印章(在右上角)
部分代码(参考)
java
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();
}
全部代码
java
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 document
PDDocument document = PDDocument.load(new File("C:\\test\\PDF\\Test.pdf"));
// Create a PDF renderer
PDFRenderer pdfRenderer = new PDFRenderer(document);
// Iterate over each page in the PDF document
for (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();
// ----end
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 document
document.close();
System.out.println("PDF converted to TIF successfully");
} catch (Exception e) {
e.printStackTrace();
}
}
}
===
===
印章(改进版)(坐标自己定义)
初版 (修改前 Base)
java
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 document
PDDocument document = PDDocument.load(new File("C:\\test\\PDF\\Test.pdf"));
// Create a PDF renderer
PDFRenderer pdfRenderer = new PDFRenderer(document);
// Iterate over each page in the PDF document
for (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 document
document.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();
}
}
定义坐标位置
效果
代碼(修改后可用代碼)
java
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 document
PDDocument document = PDDocument.load(new File("C:\\test\\PDF\\Test.pdf"));
// Create a PDF renderer
PDFRenderer pdfRenderer = new PDFRenderer(document);
// Iterate over each page in the PDF document
for (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 document
document.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图片
java
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 document
PDDocument document = PDDocument.load(new File("C:\\test\\PDF\\Java.pdf"));
// Create a PDF renderer
PDFRenderer pdfRenderer = new PDFRenderer(document);
// Iterate over each page in the PDF document
for (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 document
document.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博客
====