簡體   English   中英

使用Itext將Pdf頁轉換為Byte數組

[英]Convert Pdf pages to Byte array using Itext

我的問題

我正在尋找一種將單個pdf頁面轉換為byte []的方法(每個pdf頁面一個字節[]),這樣我就可以將它們轉換為BufferedImage []。

這樣,所有轉換都在內存中完成,而不是制作臨時文件,從而使轉換更快,更省力。 稍后我也可以將字節數組用於服務調用。 如果我可以只讓庫繼續使用itext會很好,但是,如果沒有其他方法,我可以使用其他庫。

我現在有什么

這是我目前擁有的代碼

public static BufferedImage toBufferedImage(byte[] input) throws IOException {
    InputStream in = new ByteArrayInputStream(input);
    BufferedImage bimg = ImageIO.read(in);
    return bimg;
}

public static BufferedImage[] extract(final String fileName) throws IOException {
    PdfReader reader = new PdfReader(fileName);
    int pageNum = reader.getNumberOfPages();
    BufferedImage[] imgArray = new BufferedImage[pageNum];

    for (int page = 0; page < pageNum; page++) {
        //TODO: You may need to decode the bytearray first?
        imgArray[page] = toBufferedImage(reader.getPageContent(pageNum)); 
    }

    reader.close();
    return imgArray;
}

public static void convert() throws IOException {
    String fileName = getProps("file_in");
        BufferedImage[] bim = extract(fileName);
        // close streams; Closed implicitily by try-with-resources

}

這是到目前為止我已經檢出的鏈接的(非代表性)列表。

有用,但不是我想要的

使用其他庫

我做了一些挖掘,並提出了解決方案! 希望其他人在需要時可以找到它,並且它會盡可能地幫助您。 干杯!

擴展RenderListener類

我環顧四周,發現了這一點。 通過查看代碼和類,我發現PdfImageObjects具有一個getBufferedImage() ,這正是我想要的。 現在,無需轉換為byte[] ,這是我本來以為要做的事情。 使用給定的示例代碼,我想到了這個類:

public class MyImageRenderListener implements RenderListener {

protected String path = "";
protected ArrayList<BufferedImage> bimg = new ArrayList<>();

/**
 * Creates a RenderListener that will look for images.
 */
public MyImageRenderListener(String path) {
    this.path = path;
}

public ArrayList<BufferedImage> getBimgArray() {
    return bimg;
}

/**
 * @see com.itextpdf.text.pdf.parser.RenderListener#renderImage(
 * com.itextpdf.text.pdf.parser.ImageRenderInfo)
 */
public void renderImage(ImageRenderInfo renderInfo) {
    try {

        PdfImageObject image = renderInfo.getImage();

        if (image == null) {
            return;
        }
        bimg.add(image.getBufferedImage());

    } catch (IOException e) {
        System.out.println(e.getMessage());
    }
}

與上面的鏈接相比,這里需要注意的重要更改是添加了新字段ArrayList<BufferedImage> bimg ,該字段的吸氣劑以及renderImage()函數的重組。

我還更改了項目其他類中的一些方法:

將PDF擴展為BufferedImage的代碼[]

// Credit to Mihai. Code found here: http://stackoverflow.com/questions/6851385/save-tiff-ccittfaxdecode-from-pdf-page-using-itext-and-java
public static ArrayList<BufferedImage> getBufImgArr(final String BasePath) throws IOException {

    PdfReader reader = new PdfReader(BasePath);
    PdfReaderContentParser parser = new PdfReaderContentParser(reader);
    MyImageRenderListener listener = new MyImageRenderListener(BasePath + "extract/image%s.%s");

    for (int page = 1; page <= reader.getNumberOfPages(); page++) {
        parser.processContent(page, listener);
    }

    reader.close();
    return listener.getBimgArray();

}

用於將BufferedImage []轉換為多頁Tiff的代碼

public static void convert(String fin) throws FileNotFoundException, IOException {

    ArrayList<BufferedImage> bimgArrL = getBufImgArr(fin);
    BufferedImage[] bim = new BufferedImage[bimgArrL.size()];
    bimgArrL.toArray(bim);

    try (RandomAccessOutputStream rout = new FileCacheRandomAccessOutputStream(
        new FileOutputStream("/path/you/want/result/to/go.tiff"))) {

        // The options for the tiff file are set here. 
        // **THIS BLOCK USES THE ICAFE LIBRARY TO CONVERT TO MULTIPAGE-TIFF**
        // ICAFE: https://github.com/dragon66/icafe
        ImageParam.ImageParamBuilder builder = ImageParam.getBuilder();
        TIFFOptions tiffOptions = new TIFFOptions();
        tiffOptions.setApplyPredictor(true);
        tiffOptions.setTiffCompression(Compression.CCITTFAX4);
        tiffOptions.setDeflateCompressionLevel(0);
        builder.imageOptions(tiffOptions);
        TIFFTweaker.writeMultipageTIFF(rout, bim);
        // I found this block of code here: https://github.com/dragon66/icafe/wiki
        // About 3/4 of the way down the page

    }
}

開始整個過程​​:

public static void main(String[] args){
    convert("/path/to/pdf/image.pdf");
}

重要說明:

您可能會注意到,我的代碼中從未顯式調用過listener.renderImage() 似乎renderImage()是一個輔助函數,當偵聽器對象傳遞到解析器對象時,該函數會在其他地方調用。 這發生在getBufImgArr(param)方法中。

正如下面評論中的@mkl所指出的那樣,該代碼正在提取pdf頁面中的所有圖像,因為pdf頁面本身並不是圖像。 如果您在使用OCR掃描的pdf或具有多層的pdf上運行此代碼,則可能會出現問題。 在這種情況下,當您(可能)希望將它們合並在一起放在一個頁面上時,您會將一個pdf頁面中的多個圖像轉換為多個tiff圖像。

我發現的好資料:

Programcreek搜索PdfReaderContentParser

暫無
暫無

聲明:本站的技術帖子網頁,遵循CC BY-SA 4.0協議,如果您需要轉載,請注明本站網址或者原文地址。任何問題請咨詢:yoyou2525@163.com.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM