ArifMustafa
ArifMustafa

Reputation: 4955

Retrieve Text from PDF Barcode Images using iText

I have created a PDF by inserting 2 types Bar codes QRCode and Code128 respectively.

Now my problem is how to extract the Bar Codes Images first and secondly the Text back from those Images, please help me on this, I tried and Google for 2 days but found nothing as suitable way.

Well I am using itextpdf-5.5.8 release.

Upvotes: 1

Views: 6025

Answers (2)

ArifMustafa
ArifMustafa

Reputation: 4955

Well as before I commented about a trick for Code128 Barcode Image was not getting the mouse click select in pdf, as the QRCode.

So, I store the Code128 Barcode Images as File in a tmp folder and later I inserted those Images from files, by doing this I got the Barcode Image mouse click complete Image select with Help of javaxt.io.Image api.

Here is the code the time How do I insert the Code128 Barcode Image in PDF -

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);
}

and now How do I First Extract the Barcode Image using iText and later Retrieve the String values from those Images using zxing api -

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) {}
}

Upvotes: 0

Ishan Adarsh
Ishan Adarsh

Reputation: 151

I'm also working on a similar kind of Project but its in .NET. I'm giving an optional solution for the second issue that is reading the barcode from an image. You can use ZXing for decoding barcode. Below is the pseudo-code, you have to pass the image path in the function :

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");
    }
}

Upvotes: 1

Related Questions