在工作中,遇到一个需要将pdf转为tif并将图片大小限制到30kb以内的需求。在网上看了一圈,也因为依赖版本等等踩了一些坑,为此记录下来学习的过程。


点击查看代码


import com.github.jaiimageio.impl.plugins.tiff.TIFFImageWriterSpi;
import com.github.jaiimageio.plugins.tiff.BaselineTIFFTagSet;
import com.github.jaiimageio.plugins.tiff.TIFFDirectory;
import com.github.jaiimageio.plugins.tiff.TIFFField;
import com.github.jaiimageio.plugins.tiff.TIFFTag;
import org.apache.log4j.BasicConfigurator;
import org.apache.log4j.Logger;
import org.apache.pdfbox.pdmodel.PDDocument;
import org.apache.pdfbox.pdmodel.PDPage;
import org.apache.pdfbox.rendering.ImageType;
import org.apache.pdfbox.rendering.PDFRenderer;

import javax.imageio.*;
import javax.imageio.metadata.IIOInvalidTreeException;
import javax.imageio.metadata.IIOMetadata;
import javax.imageio.stream.ImageOutputStream;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.*;
import java.util.ArrayList;
import java.util.List;


public class TifUtils {
    private static Logger logger = Logger.getLogger(TifUtils.class);
    public static void main(String[] args) throws FileNotFoundException {
        // 初始化 Log4j
        BasicConfigurator.configure();
        File file = new File("/Users/xu/testpdf/test.pdf");
        FileInputStream fileInputStream = new FileInputStream(file);
        String dir = "/Users/xu/testpdf";
        pdf2tif(file, new File(dir), 200);
    }
    public static List pdf2tif(File file1, File dir, int dpi) {
        try (PDDocument pdf = PDDocument.load(file1)) {
            BufferedImage[] images = new BufferedImage[pdf.getNumberOfPages()];
            PDFRenderer pdfRenderer = new PDFRenderer(pdf);
            List files = new ArrayList<>();
            long suffix = System.currentTimeMillis();
            for (int i = 0; i < images.length; i++) {
              //  PDPage page = (PDPage) pdf.getDocumentCatalog().getAllPages().get(i);
                PDPage page1 = pdf.getPage(i);
                BufferedImage image;
             //tif需要黑白二进制图像 所以使用ImageType.BINARY
                BufferedImage binaryImage = pdfRenderer.renderImageWithDPI(i, 300, ImageType.BINARY);
                images[i] = binaryImage;
                File file = new File(dir.getAbsolutePath() + File.separator + suffix + "-" + (i + 1) + ".tiff");
                try (FileOutputStream out = new FileOutputStream(file); ImageOutputStream ios = ImageIO.createImageOutputStream(out)) {
                    TIFFImageWriterSpi tiffWriter = new TIFFImageWriterSpi();
                    ImageWriter writer = tiffWriter.createWriterInstance();
                    ImageWriteParam param = writer.getDefaultWriteParam();
                    param.setCompressionMode(ImageWriteParam.MODE_EXPLICIT);
                    //转为tif设置的条件 如果需要其他格式可设置LZW,jpeg,png
                    param.setCompressionType("CCITT T.6");
                    //可以根据需要调整清晰程度 1为无损
                    param.setCompressionQuality(1);
					//设置图像200dpi
                    IIOMetadata metadata = createMetadata(writer, param, 200);
                    writer.setOutput(ios);
                    writer.write(metadata, new IIOImage(binaryImage, null, metadata), param);
                   logger.info("第"+(i+1)+"张图片 convert success");
                    logger.error("第"+(i+1)+"张图片 convert success");
                } catch (IOException e) {
                   // logger.error(e);;
                }
                files.add(file);

            }
            return files;
        } catch (IOException e) {
            e.printStackTrace();
            return null;
        }
    }

//修改tif图片元数据
    private static IIOMetadata createMetadata(ImageWriter writer, ImageWriteParam writerParams, int resolution) throws IIOInvalidTreeException {
        // Get default metadata from writer
        ImageTypeSpecifier type = writerParams.getDestinationType();
        IIOMetadata meta = writer.getDefaultImageMetadata(type, writerParams);
        // Convert default metadata to TIFF metadata
        TIFFDirectory dir = TIFFDirectory.createFromMetadata(meta);
        // Get {X,Y} resolution tags
        BaselineTIFFTagSet base = BaselineTIFFTagSet.getInstance();
        TIFFTag tagXRes = base.getTag(BaselineTIFFTagSet.TAG_X_RESOLUTION);
        TIFFTag tagYRes = base.getTag(BaselineTIFFTagSet.TAG_Y_RESOLUTION);
        // Create {X,Y} resolution fields
        TIFFField fieldXRes = new TIFFField(tagXRes, TIFFTag.TIFF_RATIONAL, 1, new long[][]{{resolution, 1}});
        TIFFField fieldYRes = new TIFFField(tagYRes, TIFFTag.TIFF_RATIONAL, 1, new long[][]{{resolution, 1}});
        // Add {X,Y} resolution fields to TIFFDirectory
        dir.addTIFFField(fieldXRes);
        dir.addTIFFField(fieldYRes);
//下面这行代码我是需要将tif图片像素单位改为厘米RESOLUTION_UNIT_CENTIMETER,也可以根据自己需要改为英寸
        dir.addTIFFField(new TIFFField(base.getTag(BaselineTIFFTagSet.TAG_RESOLUTION_UNIT), BaselineTIFFTagSet.RESOLUTION_UNIT_CENTIMETER));
        // Return TIFF metadata so it can be picked up by the IIOImage
        return dir.getAsMetadata();
    }
    private static BufferedImage convertToBinaryImage(BufferedImage image) {
        BufferedImage binaryImage = new BufferedImage(
                image.getWidth(), image.getHeight(),
                BufferedImage.TYPE_BYTE_BINARY);

        Graphics2D g2d = binaryImage.createGraphics();
        g2d.drawImage(image, 0, 0, null);
        g2d.dispose();

        return binaryImage;
    }

}
依赖版本:jai-imageio-core-1.3.1.jar pdfbox.2.0.9 fontbox 2.0.9
点击查看代码
    <dependencies>
        <!-- https://mvnrepository.com/artifact/org.apache.pdfbox/fontbox -->
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>fontbox</artifactId>
            <version>2.0.9</version>
        </dependency>
        <dependency>
            <groupId>org.apache.pdfbox</groupId>
            <artifactId>pdfbox</artifactId>
            <version>2.0.9</version>
        </dependency>
        <dependency>
            <groupId>log4j</groupId>
            <artifactId>log4j</artifactId>
            <version>1.2.9</version>
        </dependency>
        <dependency>
            <groupId>commons-io</groupId>
            <artifactId>commons-io</artifactId>
            <version>2.11.0</version>
        </dependency>
<dependency>
	<groupId>com.github.jai-imageio</groupId>
	<artifactId>jai-imageio-core</artifactId>
	<version>1.3.1</version>
</dependency>

    </dependencies>
jai这个包maven可能拉不下来,可以在github上下载 或者这个链接[jai 1.3.1 jar下载](https://nowjava.com/jar/detail/m00905923/jai-imageio-core-1.3.1.jar.html "jai 1.3.1 jar下载")
posted on 2023-12-27 16:50  卑鄙的风  阅读(341)  评论(0)    收藏  举报