Apache PDF 文件转图片

Java常用方法   2025-01-09 00:47   168   0  


一、基于 maven 的 Java 工程


1、pom 依赖

<?xml version="1.0" encoding="UTF-8"?>
<project xmlns="http://maven.apache.org/POM/4.0.0" xmlns:xsi="http://www.w3.org/2001/XMLSchema-instance"
         xsi:schemaLocation="http://maven.apache.org/POM/4.0.0 https://maven.apache.org/xsd/maven-4.0.0.xsd">
    <modelVersion>4.0.0</modelVersion>
    <artifactId>pdftoimages</artifactId>
    <name>pdftoimages</name>
    <version>1.0</version>
    <groupId>chenwc</groupId>
    <packaging>jar</packaging>
    <properties>
        <java.version>1.8</java.version>
        <slf4j.version>1.7.36</slf4j.version>
        <pdfbox.version>2.0.27</pdfbox.version>
        <log4j.version>1.2.17</log4j.version>
        <maven.compiler.plugin.version>3.6.1</maven.compiler.plugin.version>
    </properties>
    <dependencies>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>${pdfbox.version}</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>fontbox</artifactId>
            <version>${pdfbox.version}</version>
        </dependency>
        <dependency>
            <groupId>org.slf4j</groupId>
            <artifactId>slf4j-reload4j</artifactId>
            <version>${slf4j.version}</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>${log4j.version}</version>
            <type>pom</type>
        </dependency>
    </dependencies>

    <build>
        <plugins>
            <plugin>
                <groupId>org.apache.maven.plugins</groupId>
                <artifactId>maven-compiler-plugin</artifactId>
                <version>${maven.compiler.plugin.version}</version>
            </plugin>
        </plugins>
    </build>

</project>


2、PdfToIamges.java

package com.chenwc.pdftoiamges;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPageTree;
import org.apache.pdfbox.rendering.PDFRenderer;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import javax.imageio.ImageIO;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.zip.ZipEntry;
import java.util.zip.ZipOutputStream;

/**
 * 把pdf文件转换成图片文件
 *
 * @author chenwc
 */
public class PdfToIamges {

    private static final Logger log = LoggerFactory.getLogger(PdfToIamges.class);

    /**
     * 把pdf文件转换成 jpg 图片文件,默认输出到和pdf同级目录下
     * 图片DPI默认为300
     * 每页pdf输出一个图片文件
     *
     * @param sourceFile pdf文件
     */
    public static void pdfFileToImageFile(File sourceFile) {
        String fileName = sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf("."));
        String outputPath = sourceFile.getAbsolutePath().replace(sourceFile.getName(), "") + fileName;
        pdfFileToImageFile(sourceFile, outputPath, ImageTypeEnum.JPG, 300, false, "");
    }

    /**
     * 把pdf文件转换成 jpg 图片文件
     * 图片DPI默认为300
     * 每页pdf输出一个图片文件
     *
     * @param sourceFile pdf文件
     * @param outputPath 转换后的图片输出保存目录,如:D:\png
     */
    public static void pdfFileToImageFile(File sourceFile, String outputPath) {
        pdfFileToImageFile(sourceFile, outputPath, ImageTypeEnum.JPG, 300, false, "");
    }

    /**
     * 把pdf文件转换成 jpg 图片文件
     * 图片DPI默认为300
     * 每页pdf输出一个图片文件
     *
     * @param sourceFile pdf文件
     * @param outputPath 转换后的图片输出保存目录,如:D:\png
     * @param imageTypeEnum   输出图片文件类型
     * @param dpi        输出图片分辨率
     */
    public static void pdfFileToImageFile(File sourceFile, String outputPath, ImageTypeEnum imageTypeEnum, float dpi) {
        pdfFileToImageFile(sourceFile, outputPath, imageTypeEnum, dpi, false, "");
    }

    /**
     * 把pdf文件转换成图片文件,并压缩成zip文件
     *
     * @param sourceFile pdf文件
     * @param outputPath 转换后的图片输出保存目录,如:D:\png
     * @param zipFileName zip压缩文件名
     */
    public static void pdfFileToImageFileAndZip(File sourceFile, String outputPath, String zipFileName) {
        pdfFileToImageFile(sourceFile, outputPath, ImageTypeEnum.JPG, 300, true, zipFileName);
    }
    /**
     * 把pdf文件转换成图片文件,并压缩成zip文件
     *
     * @param sourceFile pdf文件
     * @param outputPath 转换后的图片输出保存目录,如:D:\png
     */
    public static void pdfFileToImageFileAndZip(File sourceFile, String outputPath) {
        pdfFileToImageFile(sourceFile, outputPath, ImageTypeEnum.JPG, 300, true, sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf(".")));
    }

    /**
     * 把pdf文件转换成图片文件,并压缩成zip文件,默认输出到和pdf同级目录下
     *
     * @param sourceFile pdf文件
     */
    public static void pdfFileToImageFileAndZip(File sourceFile) {
        String fileName = sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf("."));
        String outputPath = sourceFile.getAbsolutePath().replace(sourceFile.getName(), "") + fileName;
        pdfFileToImageFile(sourceFile, outputPath, ImageTypeEnum.JPG, 300, true, sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf(".")));
    }
    /**
     * 把pdf文件转换成图片文件,每页pdf输出一个图片文件
     *
     * @param sourceFile pdf文件
     * @param outputPath 转换后的图片输出保存目录,如:D:\png
     * @param typeEnum   输出图片文件类型
     * @param dpi        输出图片分辨率
     * @param isPackageZip 是否把输出目录压缩成zip文件
     * @param zipFileName zip压缩文件名
     */
    public static void pdfFileToImageFile(File sourceFile, String outputPath, ImageTypeEnum typeEnum, float dpi, boolean isPackageZip, String zipFileName) {

        long start = System.nanoTime();
        log.info("待转换 PDF 文件: {}", sourceFile.getAbsolutePath());
        log.info("转换后的图片输出保存目录: {}", outputPath);
        log.info("输出图片文件类型: {}", typeEnum.getImageType());
        log.info("输出图片分辨率: {}", dpi);
        PDDocument doc = null;
        ByteArrayOutputStream os = null;
        InputStream stream = null;
        OutputStream out = null;
        try {
            // pdf路径
            stream = new FileInputStream(sourceFile);
            // 加载解析PDF文件
            doc = PDDocument.load(stream);
            PDFRenderer pdfRenderer = new PDFRenderer(doc);
            PDPageTree pages = doc.getPages();
            int pageCount = pages.getCount();
            log.info("PDF 文件页数: {}", pageCount);
            //获取不带后缀的文件名
            String fileName = sourceFile.getName().substring(0, sourceFile.getName().lastIndexOf("."));
            for (int i = 0; i < pageCount; i++) {
                log.info("正在转换第: {} 页 PDF 文件为图片......", (i + 1));
                //设置DPI
                BufferedImage bim = pdfRenderer.renderImageWithDPI(i, dpi);
                os = new ByteArrayOutputStream();
                ImageIO.write(bim, typeEnum.getImageType(), os);
                byte[] dataList = os.toByteArray();
                // 图片文件转出路径
                File file = new File(outputPath + "\\" + fileName + "_" + i + "." + typeEnum.getImageType());
                if (!file.getParentFile().exists()) {
                    // 不存在则创建父目录及子文件
                    file.getParentFile().mkdirs();
                    file.createNewFile();
                }
                out = new FileOutputStream(file);
                out.write(dataList);
            }
            if (isPackageZip){
                packageZip(outputPath, zipFileName);
            }
            long end = System.nanoTime();
            log.info("PDF 文件转换为图片完成!");
            log.info("转换耗时: {} ms", (end - start) / 1000000.00);
        } catch (Exception e) {
            e.printStackTrace();
        } finally {
            try {
                if (doc != null) doc.close();
                if (os != null) os.close();
                if (stream != null) stream.close();
                if (out != null) out.close();
            } catch (Exception e2) {
                // TODO: handle exception
                e2.printStackTrace();
            }
        }
    }

    /**
     * 压缩文件夹为zip文件,放于和需要压缩的文件夹同级目录
     *
     * @param filesPath 要被压缩的文件夹
     * @param zipFileName zip压缩文件名
     */
    private static void packageZip(String filesPath, String zipFileName) {
        try {
            // 要被压缩的文件夹
            File file = new File(filesPath);
            if (zipFileName.contains(".zip")){
                zipFileName = zipFileName.replace(".zip", "");
            }
            filesPath = filesPath.substring(0, filesPath.lastIndexOf("\\") + 1);
            //放于和需要压缩的文件夹同级目录
            File zipFile = new File(filesPath + zipFileName + ".zip");
            log.info("正在输出 zip 压缩文件: {}", zipFile.getAbsolutePath());
            ZipOutputStream zipOut = new ZipOutputStream(new FileOutputStream(zipFile));
            //判断是否为文件夹
            isDirectory(file, zipOut, "", true);
            zipOut.close();
            log.info("zip 文件压缩完成!");
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 判断是否为文件夹,是文件夹则递归,不是目录则压缩文件
     *
     * @param file            需要压缩的文件夹
     * @param zipOutputStream zipOutputStream
     * @param filePath        根目录,默认为 ""
     * @param flag            判断是否为根目录,默认为true
     */
    private static void isDirectory(File file, ZipOutputStream zipOutputStream, String filePath, boolean flag) {
        try {
            //判断是否为目录
            if (file.isDirectory()) {
                //获取该文件夹下所有文件(包含文件夹)
                File[] files = file.listFiles();
                //首次为选中的文件夹,即根目录,之后递归实现拼接目录
                filePath = flag ? file.getName() : filePath + File.separator + file.getName();
                if (null == files) {
                    return;
                }
                for (File value : files) {
                    //判断子文件是否为文件夹
                    if (value.isDirectory()) {
                        //进入递归,flag置false 即当前文件夹下仍包含文件夹
                        isDirectory(value, zipOutputStream, filePath, false);
                    } else {
                        //不为文件夹则进行压缩
                        InputStream input = new FileInputStream(value);
                        zipOutputStream.putNextEntry(new ZipEntry(filePath + File.separator + value.getName()));
                        int temp = 0;
                        while ((temp = input.read()) != -1) {
                            zipOutputStream.write(temp);
                        }
                        input.close();
                    }
                }
            } else {
                //将子文件夹下的文件进行压缩
                InputStream input = new FileInputStream(file);
                zipOutputStream.putNextEntry(new ZipEntry(file.getPath()));
                int temp = 0;
                while ((temp = input.read()) != -1) {
                    zipOutputStream.write(temp);
                }
                input.close();
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

    }
}


3、ImageTypeEnum.java

package com.chenwc.pdftoiamges;

public enum ImageTypeEnum {

    PNG("png"),
    JPG("jpg"),
    BMP("bmp");

    ImageTypeEnum(String imageType) {
        this.imageType = imageType;
    }

    private String imageType;

    public String getImageType() {
        return imageType;
    }

    public void setImageType(String imageType) {
        this.imageType = imageType;
    }
}


4、log4j.properties

log4j.rootLogger=info,stdout
log4j.appender.stdout=org.apache.log4j.ConsoleAppender
log4j.appender.stdout.Target=System.out
log4j.appender.stdout.layout=org.apache.log4j.PatternLayout
log4j.appender.stdout.layout.ConversionPattern=%d %-5p %-5L --- [%-5t] %-10c : %m %n


二、基于 Eclipse 的纯 Java 工程

1、依赖

log4j-1.2.17.jar
slf4j-api-1.7.36.jar
slf4j-log4j12-1.7.7.jar
fontbox-2.0.27.jar
pdfbox-2.0.27.jar
commons-logging-1.2.jar


上一篇
博客评论
还没有人评论,赶紧抢个沙发~
发表评论
说明:请文明发言,共建和谐网络,您的个人信息不会被公开显示。