使用 iText 从 PDF 条码图像中检索文本

Retrieve Text from PDF Barcode Images using iText

我通过分别插入两种类型的条形码 QRCode 和 Code128 创建了一个 PDF。

现在我的问题是如何首先提取条形码图像,然后从这些图像中提取文本, 请帮助我解决这个问题,我尝试 Google 了 2 天,但没有找到合适的方法。

嗯,我正在使用 itextpdf-5.5.8 版本。

我也在从事类似的项目,但它是在 .NET 中进行的。我为第二个问题提供了一个可选的解决方案,即从图像中读取条形码。您可以使用 ZXing 解码条码。下面是伪代码,你必须在函数中传递图像路径:

static void ScanBarCode(string FileName) {
    System.Drawing.Bitmap bitmap = new System.Drawing.Bitmap(FileName);
    try {
        BarcodeReader reader = new BarcodeReader { AutoRotate = true, TryHarder = true };
        Result result = reader.Decode(bitmap);
        string decodedData = result.Text;
        Console.WriteLine(result.ToString());
    } catch {
        throw new Exception("Cannot decode the Barcode code");
    }
}

和之前一样,我评论过 Code128 Barcode Image 的一个技巧是无法在 pdf 中单击鼠标 select,因为 QRCode。

因此,我将 Code128 Barcode 图像存储为 File 在 tmp 文件夹中,稍后我从文件中插入这些图像,通过这样做我得到了 Barcode Image 鼠标单击完成图像select 在 javaxt.io.Image api.

的帮助下

这是时间代码如何在PDF中插入Code128 Barcode Image -

private static void insertBAR(PdfContentByte cb, PdfPTable table, String text, int colspan, com.itextpdf.text.Font font){
    Barcode128 code128 = new Barcode128();
    code128.setBaseline(-1);
    code128.setSize(16f);
    //code128.setBarHeight(16f);
    code128.setCode(text.trim());
    code128.setCodeType(Barcode128.CODE128);
    Image code128Image = code128.createImageWithBarcode(cb, new BaseColor(0, 47, 47), null);

    java.awt.Image awtImage = code128.createAwtImage(new Color(0, 47, 47), Color.WHITE);
    //java.awt.Image awtImage = code128.createAwtImage(Color.BLACK, Color.WHITE);
    //Initialising a 6+ (width and height)size of BufferedImage to put the Barcode Image in center
    BufferedImage bi = new BufferedImage(awtImage.getWidth(null)+6, awtImage.getHeight(null)+6, BufferedImage.TYPE_INT_ARGB);

    Graphics2D gd = bi.createGraphics();
    gd.setColor(Color.WHITE);
    gd.fillRect(0, 0, bi.getWidth(), bi.getHeight());
    //drawing the Barcode Image in center of BufferedImage Rect.
    gd.drawImage(awtImage, 3, 3, null);
    gd.dispose();

    File imgFile = new File(OneMethod.getElementosPath() + "/db/tmp/Img" + (++shortCount) + ".png");

    try {
        javaxt.io.Image img = new javaxt.io.Image(bi);
        img.saveAs(imgFile);
    code128Image = Image.getInstance(imgFile.getAbsolutePath());
    } catch (BadElementException | IOException ex) {
        ex.printStackTrace();
    }

    PdfPCell cell = new PdfPCell();
    cell.setMinimumHeight(35f);
    cell.setHorizontalAlignment(Element.ALIGN_LEFT);
    cell.setVerticalAlignment(Element.ALIGN_MIDDLE);
    cell.setPadding(2f);
    cell.setColspan(colspan);
    cell.addElement(code128Image);
    //cell.setImage(code128Image);
    table.addCell(cell);
}

现在我如何首先使用 iText 提取 Barcode Image 然后使用 zxing api 从这些图像中检索 String 值 -

private void readAndValidateContents(){
    if(externalLOB.size() == 2){
        try {       
            PdfReader reader = new PdfReader(externalLOB.get(0).getAbsolutePath());     
            PdfReaderContentParser parser = new PdfReaderContentParser(reader);
            //Trying to Extract Images to a tmp folder
            ImageRenderListener listener = new ImageRenderListener(OneMethod.getElementosPath() + "/db/tmp/Img%s.%s");

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

            //Retrieving String values from images extracted to tmp folder
            ArrayList<String> ary = OneMethod.decodeBarcodes();

            //Extracting String values from PDF Page using iText API
            String[] contents = (PdfTextExtractor.getTextFromPage(reader, 1)).split("\n");
            externalKey.clear();

            System.out.println("\n\n");

            short line = 0;
            for(String str : contents){
                System.out.println(line++ + str);
            }

            String tempVal = ary.get(0);
            String[] split = tempVal.split("\n");
            tempVal = split[0];

            tempVal = tempVal.substring(0, tempVal.indexOf("."));
            System.out.println("\n\n" + tempVal + "\n\n");

            if(contents[4].equals(tempVal)){ //comparing qr bar code file name with pdf text file name  
                System.out.println("Something XYZ....Here...Done...")
            }else{
                System.err.println("Possibilities for File Interruption, File different of requested...");
            }           
        } catch (StringIndexOutOfBoundsException spiobe){
            System.err.println("File different of requested...");
        } catch (IOException ioe) {
            ioe.printStackTrace();
        } catch (Exception ex){
            ex.printStackTrace();
        } finally{
            OneMethod.clearDirectory(OneMethod.getElementosPath() + "/db/tmp/");
        }
    }
}

class OneMethod {
    static synchronized ArrayList<String> decodeBarcodes(){
        ArrayList<String> ary = new ArrayList<String>();
        short suffix = 1;
        File imageFile = null;

        outer:
        while(true){
            if(++suffix > 5) //Starting to read the Img with Suffix 2 i.e. Img2.jpg
                break outer;
            inner:
            while(true){
                try{
                    InputStream barCodeInputStream;
                    imageFile = new File(OneMethod.getElementosPath() 
                        + "/db/tmp/Img" + suffix + (suffix != 2 ? ".png" : ".jpg"));
                    if(imageFile.exists() && imageFile.isFile()){
                        barCodeInputStream = new FileInputStream(imageFile.getAbsolutePath());
                        BufferedImage barCodeBufferedImage = ImageIO.read(barCodeInputStream);

                        //Using zxing-core-3.2.0 with collaborating the old 1.3 version com.google.zxing.client.j2se package inside.
                        //So doing above action you will get the BufferedImageLuminanceSource class which is now not available in new versions.

                        LuminanceSource source = new BufferedImageLuminanceSource(barCodeBufferedImage);
                        BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
                        Reader reader = new MultiFormatReader();
                        Result result = reader.decode(bitmap);

                        System.out.println(suffix + " value is : " + result.getText());

                        ary.add(result.getText());
                    }else{
                        System.out.println(imageFile.getAbsolutePath() + " path is not available...");
                    }
                    break inner;
                } catch(FileNotFoundException | NullPointerException ex) {
                    ex.printStackTrace();
                } catch (IOException ex) {
                    ex.printStackTrace();
                } catch (NotFoundException | ChecksumException | FormatException ex) {
                    ex.printStackTrace();
                }
            }
        }       
        return ary;
    }

    static synchronized void clearDirectory(final String dirPath){
        new Thread(new Runnable(){
            public void run(){
                try{
                    File directory = new File(dirPath);
                    if(directory.isDirectory() == true)
                        try {
                            File[] files = directory.listFiles();
                            for(File file : files){
                                FileUtils.deleteQuietly(file);
                                Thread.sleep(100);
                                if(file.exists())
                                    FileUtils.forceDeleteOnExit(file);
                            }
                        } catch (IOException ioe) {
                            ioe.printStackTrace();
                        }
                }catch(InterruptedException exp){
                    exp.printStackTrace();
                }
            }
        }).start();
    }
}

class ImageRenderListener implements RenderListener { 
    /**
     * Creates a RenderListener that will look for images.
    */
    public ImageRenderListener(String path) {
        this.path = path;
        tempCount = 0;
    }

    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#beginTextBlock()
     */
    public void beginTextBlock() {}

    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#endTextBlock()
     */
    public void endTextBlock() {}

    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#renderImage(
     *     com.itextpdf.text.pdf.parser.ImageRenderInfo)
    */
    public void renderImage(ImageRenderInfo renderInfo) {
    //public void renderImage(InlineImageInfo renderInfo) {
        try {
            String filename;
            FileOutputStream os;
            PdfImageObject image = renderInfo.getImage();
            if (image == null) return;
            filename = String.format(path, ++tempCount, image.getFileType());
            os = new FileOutputStream(filename);
            os.write(image.getImageAsBytes());
            os.flush();
            os.close();
        } catch (IOException e) {
            System.out.println(e.getMessage());
        }
    }

    /**
     * @see com.itextpdf.text.pdf.parser.RenderListener#renderText(
     *     com.itextpdf.text.pdf.parser.TextRenderInfo)
    */
    public void renderText(TextRenderInfo renderInfo) {}
}