Java PDF转图片

1.pom.xml文件配置

<!--pdf转图片 -->
<dependency>
	<groupId>org.apache.pdfbox</groupId>
	<artifactId>fontbox</artifactId>
	<version>2.0.1</version>
</dependency>
<dependency>
	<groupId>org.apache.pdfbox</groupId>
	<artifactId>pdfbox</artifactId>
	<version>2.0.1</version>
</dependency>

2.工具类

import cn.hutool.core.codec.Base64Decoder;
import cn.hutool.core.util.StrUtil;
import lombok.extern.slf4j.Slf4j;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;
import sun.misc.BASE64Decoder;
import sun.misc.BASE64Encoder;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;

/**
 * TODO
 *
 * @Author: DYS
 * @date 2021/8/4 18:02
 * @描述:
 */
@Slf4j
public class Base64Utils {

	/**
	 * @描述: 根据base64编码生成图片,保存在Path中
	 * @Date: 2021/8/5 13:08
	 * @param base64Code:
	 * @param filePath:
	 * @param picName:
	 * @return boolean
	 * @Description: //TODO PC002
	 * @Author: DYS
	 **/
	public static boolean base64ToPic(String base64Code, String filePath, String picName) {
		if (base64Code == null) {
			return false;
		}
		//文件不存在
		File existsFilePath = new File(filePath);
		if (!existsFilePath.exists()) {
			existsFilePath.mkdirs();
		}
//        String handledBase64Code = "data:image/png;base64," + base64PdfToJpgBase64(base64Code);
		String handledBase64Code =base64PdfToJpgBase64(base64Code);
		// Base64解码
		// 替换掉多余的空格
		String replace = handledBase64Code.replaceAll(" ", "");
		BASE64Decoder decoder = new BASE64Decoder();
		try {
			//Base64解码
			byte[] b = decoder.decodeBuffer(replace);
			for (int i = 0; i < b.length; ++i) {
				if (b[i] < 0) {//调整异常数据
					b[i] += 256;
				}
			}
			//生成jpeg图片
			String path = filePath + "/" + picName + ".png";
			OutputStream out = new FileOutputStream(path);
			out.write(b);
			out.flush();
			out.close();
			return true;
		} catch (Exception e) {
			StringWriter stringWriter = new StringWriter();
			PrintWriter printWriter = new PrintWriter(stringWriter);
			e.printStackTrace();
			e.printStackTrace(printWriter);
			log.error("base64编码生成图片 error >>> " + stringWriter.toString());
			return false;
		}
	}

	//    将pdf的base64编码格式转为img的base64编码格式并合成一张图片:
	public static String base64PdfToJpgBase64(String base64Pdf) {
		if (StrUtil.isEmpty(base64Pdf)) {
			return null;
		}
		String jpg_base64 = null;
//        Base64Decoder decoder = new Base64Decoder();
		try {
			// Base64解码
			byte[] pdf_bytes = Base64Decoder.decode(base64Pdf);
			PDDocument doc = PDDocument.load(pdf_bytes);
			int size = doc.getNumberOfPages();
			/*图像合并使用的参数*/
			//定义宽度
			int width = 0;
			// 保存一张图片中的RGB数据
			int[] singleImgRGB;
			// 定义高度,后面用于叠加
			int shiftHeight = 0;
			//保存每张图片的像素值
			BufferedImage imageResult = null;
			// 利用PdfBox生成图像
			PDDocument pdDocument = doc;
			PDFRenderer renderer = new PDFRenderer(pdDocument);
			/*根据总页数, 按照50页生成一张长图片的逻辑, 进行拆分*/
			// 每50页转成1张图片
			int pageLength = size; //有多少转多少
			// 总计循环的次数
			int totalCount = pdDocument.getNumberOfPages() / pageLength + 1;
			for (int m = 0; m < totalCount; m++) {
				for (int i = 0; i < pageLength; i++) {
					int pageIndex = i + (m * pageLength);
					if (pageIndex == pdDocument.getNumberOfPages()) {
						System.out.println("循环次数 m = " + m);
						break;
					}
					// 96为图片的dpi,dpi越大,则图片越清晰,图片越大,转换耗费的时间也越多
					BufferedImage image = renderer.renderImageWithDPI(pageIndex, 150, ImageType.RGB);
					int imageHeight = image.getHeight();
					int imageWidth = image.getWidth();
					if (i == 0) {
						//计算高度和偏移量
						//使用第一张图片宽度;
						width = imageWidth;
						// 保存每页图片的像素值
						// 加个判断:如果m次循环后所剩的图片总数小于pageLength,则图片高度按剩余的张数绘制,否则会出现长图片下面全是黑色的情况
						if ((pdDocument.getNumberOfPages() - m * pageLength) < pageLength) {
							imageResult = new BufferedImage(width, imageHeight * (pdDocument.getNumberOfPages() - m * pageLength), BufferedImage.TYPE_INT_RGB);
						} else {
							imageResult = new BufferedImage(width, imageHeight * pageLength, BufferedImage.TYPE_INT_RGB);
						}
					} else {
						// 将高度不断累加
						shiftHeight += imageHeight;
					}
					singleImgRGB = image.getRGB(0, 0, width, imageHeight, null, 0, width);
					imageResult.setRGB(0, shiftHeight, width, imageHeight, singleImgRGB, 0, width);
				}
				// 这个很重要,下面会有说明
				shiftHeight = 0;
			}
			pdDocument.close();
			ByteArrayOutputStream baos = new ByteArrayOutputStream();//io流
			ImageIO.write(imageResult, "jpg", baos);//写入流中
			byte[] jpg_Bytes = baos.toByteArray();//转换成字节
			BASE64Encoder encoder = new BASE64Encoder();
			jpg_base64 = encoder.encodeBuffer(jpg_Bytes).trim();//转换成base64串
			jpg_base64 = jpg_base64.replaceAll("\n", "").replaceAll("\r", "");//删除 \r\n
			baos.close();
			doc.close();
		 } catch (IOException e) {
			e.printStackTrace();
		}
		return jpg_base64;
	}


	/**
	 * 图片生成base64编码
	 *
	 * @param imgPath
	 * @return
	 */
	public static String PicToBase64(String imgPath) {
		String result = "";
		File imgFile = new File(imgPath);
		if (!imgFile.exists()) {
			System.out.println("非法路径");
			return result;
		}
		InputStream in = null;
		byte[] data = null;
		//读取图片字节数组
		try {
			in = new FileInputStream(imgFile);
			data = new byte[in.available()];
			in.read(data);
			in.close();
		} catch (IOException e) {
			e.printStackTrace();
		}
		//对字节数组Base64编码
		BASE64Encoder encoder = new BASE64Encoder();
		return encoder.encode(data);//返回Base64编码过的字节数组字符串
	}


	public static byte[] base64ToImgByteArray(String base64) throws IOException {
		sun.misc.BASE64Decoder decoder = new sun.misc.BASE64Decoder();
		//因为参数base64来源不一样,需要将附件数据替换清空掉。如果此入参来自canvas.toDataURL("image/png");
		base64 = base64.replaceAll("data:image/png;base64,", "");
		//base64解码并转为二进制数组
		byte[] bytes = decoder.decodeBuffer(base64);
		for (int i = 0; i < bytes.length; ++i) {
			if (bytes[i] < 0) {// 调整异常数据
				bytes[i] += 256;
			}
		}
		return bytes;
	}

}
posted @   柠檬加醋!  阅读(359)  评论(0编辑  收藏  举报
相关博文:
阅读排行:
· 10年+ .NET Coder 心语 ── 封装的思维:从隐藏、稳定开始理解其本质意义
· 地球OL攻略 —— 某应届生求职总结
· 周边上新:园子的第一款马克杯温暖上架
· 提示词工程——AI应用必不可少的技术
· Open-Sora 2.0 重磅开源!
点击右上角即可分享
微信分享提示