All Downloads are FREE. Search and download functionalities are using the official Maven repository.

com.itextpdf.pdfocr.tesseract4.ImagePreprocessingUtil Maven / Gradle / Ivy

/*
    This file is part of the iText (R) project.
    Copyright (c) 1998-2021 iText Group NV
    Authors: iText Software.

    This program is offered under a commercial and under the AGPL license.
    For commercial licensing, contact us at https://itextpdf.com/sales.  For AGPL licensing, see below.

    AGPL licensing:
    This program is free software: you can redistribute it and/or modify
    it under the terms of the GNU Affero General Public License as published by
    the Free Software Foundation, either version 3 of the License, or
    (at your option) any later version.

    This program is distributed in the hope that it will be useful,
    but WITHOUT ANY WARRANTY; without even the implied warranty of
    MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the
    GNU Affero General Public License for more details.

    You should have received a copy of the GNU Affero General Public License
    along with this program.  If not, see .
 */
package com.itextpdf.pdfocr.tesseract4;

import com.itextpdf.io.image.ImageType;
import com.itextpdf.io.image.ImageTypeDetector;
import com.itextpdf.io.image.TiffImageData;
import com.itextpdf.io.util.UrlUtil;
import com.itextpdf.io.source.RandomAccessFileOrArray;
import com.itextpdf.io.source.RandomAccessSourceFactory;
import com.itextpdf.io.util.MessageFormatUtil;

import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.IOException;
import javax.imageio.ImageIO;
import net.sourceforge.lept4j.Leptonica;
import net.sourceforge.lept4j.Pix;
import org.slf4j.LoggerFactory;

/**
 * Utilities class to work with images.
 * Class provides tools for basic image preprocessing.
 */
class ImagePreprocessingUtil {

    /**
     * Creates a new {@link ImagePreprocessingUtil} instance.
     */
    private ImagePreprocessingUtil() {
    }

    /**
     * Counts number of pages in the provided tiff image.
     *
     * @param inputImage input image {@link java.io.File}
     * @return number of pages in the provided TIFF image
     * @throws IOException if error occurred during creating a
     * {@link com.itextpdf.io.source.IRandomAccessSource} based on a filename
     * string
     */
    static int getNumberOfPageTiff(final File inputImage)
            throws IOException {
        RandomAccessFileOrArray raf = new RandomAccessFileOrArray(
                new RandomAccessSourceFactory()
                        .createBestSource(
                                inputImage.getAbsolutePath()));
        int numOfPages = TiffImageData.getNumberOfPages(raf);
        raf.close();
        return numOfPages;
    }

    /**
     * Checks whether image format is TIFF.
     *
     * @param inputImage input image {@link java.io.File}
     * @return true if provided image has 'tiff' or 'tif' extension
     */
    static boolean isTiffImage(final File inputImage) {
        return getImageType(inputImage) == ImageType.TIFF;
    }

    /**
     * Gets the image type.
     *
     * @param inputImage input image {@link java.io.File}
     * @return image type {@link com.itextpdf.io.image.ImageType}
     */
    static ImageType getImageType(final File inputImage) {
        ImageType type;
        try {
            type = ImageTypeDetector.detectImageType(UrlUtil.toURL(inputImage.getAbsolutePath()));
        } catch (Exception e) { // NOSONAR
            LoggerFactory.getLogger(ImagePreprocessingUtil.class).error(MessageFormatUtil
                    .format(Tesseract4LogMessageConstant
                                    .CANNOT_READ_INPUT_IMAGE,
                            e.getMessage()));
            throw new Tesseract4OcrException(
                    Tesseract4OcrException.CANNOT_READ_PROVIDED_IMAGE)
                    .setMessageParams(inputImage.getAbsolutePath());
        }

        return type;
    }

    /**
     * Reads provided image file using stream.
     *
     * @param inputFile input image {@link java.io.File}
     * @return returns a {@link java.awt.image.BufferedImage} as the result
     * @throws IllegalArgumentException if error occurred during reading a file
     * @throws IOException if error occurred during reading a file
     */
    static BufferedImage readImageFromFile(final File inputFile)
            throws IllegalArgumentException, IOException {
        FileInputStream is = new FileInputStream(inputFile.getAbsolutePath());
        BufferedImage bi = ImageIO.read(is);
        is.close();
        return bi;
    }

    /**
     * Reads input file as Leptonica {@link net.sourceforge.lept4j.Pix} and
     * converts it to {@link java.awt.image.BufferedImage}.
     *
     * @param inputImage input image {@link java.io.File}
     * @return returns a {@link java.awt.image.BufferedImage} as the result
     * @throws IOException is error occurred during conversion from
     * {@link net.sourceforge.lept4j.Pix} to
     * {@link java.awt.image.BufferedImage}
     */
    static BufferedImage readAsPixAndConvertToBufferedImage(
            final File inputImage)
            throws IOException {
        Pix pix = Leptonica.INSTANCE
                .pixRead(inputImage.getAbsolutePath());
        return TesseractOcrUtil.convertPixToImage(pix);
    }

    /**
     * Performs basic image preprocessing using buffered image (if provided).
     * Preprocessed image will be saved in temporary directory.
     *
     * @param inputFile input image {@link File}
     * @param pageNumber number of page to be preprocessed
     * @param imagePreprocessingOptions {@link ImagePreprocessingOptions}
     * @return created preprocessed image as {@link net.sourceforge.lept4j.Pix}
     * @throws Tesseract4OcrException if it was not possible to read or convert
     * input file
     */
    static Pix preprocessImage(final File inputFile,
                               final int pageNumber,
                               final ImagePreprocessingOptions imagePreprocessingOptions)
            throws Tesseract4OcrException {
        Pix pix = null;
        // read image
        if (isTiffImage(inputFile)) {
            pix = TesseractOcrUtil.readPixPageFromTiff(inputFile,
                    pageNumber - 1);
        } else {
            pix = TesseractOcrUtil.readPix(inputFile);
        }
        if (pix == null) {
            throw new Tesseract4OcrException(
                    Tesseract4OcrException.CANNOT_READ_PROVIDED_IMAGE)
                    .setMessageParams(inputFile.getAbsolutePath());
        }
        return TesseractOcrUtil.preprocessPix(pix, imagePreprocessingOptions);
    }

    /**
     * Reads input image as a {@link java.awt.image.BufferedImage}.
     * If it is not possible to read {@link java.awt.image.BufferedImage} from
     * input file, image will be read as a {@link net.sourceforge.lept4j.Pix}
     * and then converted to {@link java.awt.image.BufferedImage}.
     * @param inputImage original input image
     * @return input image as a {@link java.awt.image.BufferedImage}
     */
    static BufferedImage readImage(File inputImage) {
        BufferedImage bufferedImage = null;
        try {
            bufferedImage = ImagePreprocessingUtil
                    .readImageFromFile(inputImage);
        } catch (IllegalArgumentException | IOException ex) {
            LoggerFactory.getLogger(ImagePreprocessingUtil.class).info(
                    MessageFormatUtil.format(
                            Tesseract4LogMessageConstant
                                    .CANNOT_CREATE_BUFFERED_IMAGE,
                            ex.getMessage()));
        }
        if (bufferedImage == null) {
            try {
                bufferedImage = ImagePreprocessingUtil
                        .readAsPixAndConvertToBufferedImage(
                                inputImage);
            } catch (IOException ex) {
                LoggerFactory.getLogger(ImagePreprocessingUtil.class)
                        .info(MessageFormatUtil.format(
                                Tesseract4LogMessageConstant
                                        .CANNOT_READ_INPUT_IMAGE,
                                ex.getMessage()));
            }
        }
        return bufferedImage;
    }
}




© 2015 - 2024 Weber Informatics LLC | Privacy Policy