JAVA->PDF转图片小工具(转为单页/多页)

pox里加一下依赖

        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>fontbox</artifactId>
            <version>2.0.2</version>
        </dependency>

然后直接上代码

package com.zjn.xxx;

import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.rendering.PDFRenderer;

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

public class PdfToImageUtil {
    /**
     * dpi越大转换后越清晰,相对转换速度越慢
     */
    private static final Integer DPI = 1000;

    /**
     * 转换后的图片类型
     */
    private static final String IMG_TYPE = "jpg";

    public static void main(String[] args) throws IOException {
        //直接在这调用就可
        //File:要转图片的pdf路径
        //Path:输出图片的路径
        //Name:输出图片的名称
        //将单/多页的pdf转成单/多张的图片
        getPicsFromStreams(pdfToImage(PdfToStreams("C:/Users/Jinni.Zi/Desktop/电子发票多张多页.pdf")),"C:/Users/Jinni.Zi/Desktop/","电子发票多张多页");
        //将单/多页的pdf转成一张长图
        getPicFromStreams(pdfToImage(PdfToStreams("C:/Users/Jinni.Zi/Desktop/电子发票多张多页.pdf")),"C:/Users/Jinni.Zi/Desktop/","电子发票多张多页");
    }


    /**
     * 将二进制流转成单张图片
     * @param bytes
     */
    public static void getPicFromStreams(List<byte[]> bytes,String Path,String Name) {
        try {
            ArrayList<BufferedImage> BufferedImageList = new ArrayList<BufferedImage>();
            for(int i=0;i<bytes.size();i++){
                ByteArrayInputStream in = new ByteArrayInputStream(bytes.get(i));
                BufferedImage image = ImageIO.read(in);     //将in作为输入流,读取图片存入image中
                BufferedImageList.add(image);
            }
            mergeVertical(BufferedImageList,Path+Name+"."+IMG_TYPE);
        } catch (IOException e) {
            e.printStackTrace();
        }
    }

    /**
     * 将二进制流转成单张/多张图片(根据pdf页数)
     * @param bytes
     */
    public static void getPicsFromStreams(List<byte[]> bytes,String Path,String Name) {
        ;//存放二进制的流
        try {
            ArrayList<File> fileList = new ArrayList<File>();
            for(int i=0;i<bytes.size();i++){
                File file = new File(Path+Name+i+"."+IMG_TYPE);
                FileOutputStream fos = new FileOutputStream(file);
                fos.write(bytes.get(i));
                fos.flush();
                fos.close();
                fileList.add(file);
            }
        } catch (IOException e) {
            e.printStackTrace();
        }
    }


    /**
     * 单/多页PDF文件的二进制流转图片
     *
     * @param fileContent 多页PDF文件的二进制流
     * @return 图片文件的二进制流
     */
    public static List<byte[]> pdfToImage(byte[] fileContent) throws IOException {
        List<byte[]> result = new ArrayList<>();
        try (PDDocument document = PDDocument.load(fileContent)) {
            PDFRenderer renderer = new PDFRenderer(document);
            for (int i = 0; i < document.getNumberOfPages(); ++i) {
                BufferedImage bufferedImage = renderer.renderImageWithDPI(i, DPI);
                ByteArrayOutputStream out = new ByteArrayOutputStream();
                ImageIO.write(bufferedImage, IMG_TYPE, out);
                result.add(out.toByteArray());
            }
        }
        return result;
    }

//   /**
//     * 将单个PDF二进制流转图片
//     *
//     * @param fileContent PDF文件的二进制流
//     * @return 图片文件的二进制流
//     */
//    public static byte[] pdfToImage2(byte[] fileContent) throws IOException {
//        byte[] result = null;
//        try (PDDocument document = PDDocument.load(fileContent)) {
//            PDFRenderer renderer = new PDFRenderer(document);
//            BufferedImage bufferedImage = renderer.renderImageWithDPI(0, DPI);
//            ByteArrayOutputStream out = new ByteArrayOutputStream();
//            ImageIO.write(bufferedImage, IMG_TYPE, out);
//            result = out.toByteArray();
//        }
//        return result;
//    }

    /**
     * 将PDF转为二进制流
     * @param File
     * @return
     * @throws IOException
     */
    public static byte[] PdfToStreams(String File) throws IOException {
        ArrayList bytesList = new ArrayList();
        byte[] bytes = new byte[1];

        FileInputStream inStream = null;
        try {
            inStream = new FileInputStream(File);
            while (inStream.read(bytes) > 0) {
                bytesList.add(bytes[0]);
            }
            bytes = new byte[bytesList.size()];
            for (int i = 0; i < bytes.length; i++) {
                bytes[i] = (byte) bytesList.get(i);
            }
            return bytes;
        } catch (Exception e) {
            e.printStackTrace();
            throw e;
        } finally {
            try {
                if (inStream != null) {
                    inStream.close();
                }
            } catch (Exception e) {
                e.printStackTrace();
            }
        }
    }

    /**
     * 垂直合成多张图片
     * @param files
     * @param path
     */
    public static void mergeVertical(List<BufferedImage> files, String path){
        try {
            Integer allWidth = 0;	//计算画布总宽
            Integer allHeight = 0;	//计算画布总高
            List<BufferedImage> imgs = new ArrayList<>();
            for(int i=0; i<files.size(); i++){
                imgs.add(files.get(i));
                //因为是竖向合成,拿图片里最大的一个宽度就行
                allWidth = Math.max(allWidth,imgs.get(i).getWidth());
                allHeight += imgs.get(i).getHeight();
            }
            BufferedImage combined = new BufferedImage(allWidth, allHeight,BufferedImage.TYPE_INT_RGB);
            Graphics g = combined.getGraphics();
            //设置画布背景颜色 ,默认黑色
            g.setColor(Color.white);
            g.fillRect(0, 0, allWidth, allHeight);
            Integer height = 0;
            for(int i=0; i< imgs.size(); i++){
                g.drawImage(imgs.get(i), 0, height,null);
                //+10为了设置上下两个图片间距
                height +=  imgs.get(i).getHeight()+10;
            }
            ImageIO.write(combined, "jpg", new File(path));
            System.out.println("===合成成功====");
        } catch (Exception e) {
            System.out.println("===合成失败====");
            e.printStackTrace();
        }
    }

}


参考:
Java多张图片合成一张(横向或竖向)–梦里梦见醒不来丶
PDF文件的二进制流转图片文件的二进制流–一路向前

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值