Find QR code in image and decode it using Zxing

29,511

Solution 1

here is the code to create the Qr-Code and read Message from Qr-code

  1. you need the build the zxing library

  2. main describe the qr-code creation and qr-code extraction

    package com.attendance.mark;
    import java.io.File;
    import java.io.FileInputStream;
    import java.io.FileNotFoundException;
    import java.io.IOException;
    import java.util.HashMap;
    import java.util.Map;
    
    import javax.imageio.ImageIO;
    
    import com.google.zxing.BarcodeFormat;
    import com.google.zxing.BinaryBitmap;
    import com.google.zxing.EncodeHintType;
    import com.google.zxing.MultiFormatReader;
    import com.google.zxing.MultiFormatWriter;
    import com.google.zxing.NotFoundException;
    import com.google.zxing.Result;
    import com.google.zxing.WriterException;
    import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
    import com.google.zxing.client.j2se.MatrixToImageWriter;
    import com.google.zxing.common.BitMatrix;
    import com.google.zxing.common.HybridBinarizer;
    import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
    
    public class QRCode {
    
        /**
         * 
         * @param args 
         * @throws WriterException
         * @throws IOException
         * @throws NotFoundException
         */
      public static void main(String[] args) throws WriterException, IOException,
          NotFoundException {
        String qrCodeData = "student3232_2015_12_15_10_29_46_123";
        String filePath = "F:\\Opulent_ProjectsDirectory_2015-2016\\.metadata\\.plugins\\org.eclipse.wst.server.core\\tmp0\\wtpwebapps\\AttendanceUsingQRCode\\QRCodes\\student3232_2015_12_15_10_29_46_123";
        String charset = "UTF-8"; // or "ISO-8859-1"
        Map<EncodeHintType, ErrorCorrectionLevel> hintMap = new HashMap<EncodeHintType, ErrorCorrectionLevel>();
        hintMap.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
    
        createQRCode(qrCodeData, filePath, charset, hintMap, 200, 200);
        System.out.println("QR Code image created successfully!");
    
        System.out.println("Data read from QR Code: "
            + readQRCode(filePath, charset, hintMap));
    
      }
    
      /***
       * 
       * @param qrCodeData
       * @param filePath
       * @param charset
       * @param hintMap
       * @param qrCodeheight
       * @param qrCodewidth
       * @throws WriterException
       * @throws IOException
       */
      public static void createQRCode(String qrCodeData, String filePath,
          String charset, Map hintMap, int qrCodeheight, int qrCodewidth)
          throws WriterException, IOException {
        BitMatrix matrix = new MultiFormatWriter().encode(
            new String(qrCodeData.getBytes(charset), charset),
            BarcodeFormat.QR_CODE, qrCodewidth, qrCodeheight);
        MatrixToImageWriter.writeToFile(matrix, filePath.substring(filePath
            .lastIndexOf('.') + 1), new File(filePath));
      }
    
      /**
       * 
       * @param filePath
       * @param charset
       * @param hintMap
       * 
       * @return Qr Code value 
       * 
       * @throws FileNotFoundException
       * @throws IOException
       * @throws NotFoundException
       */
      public static String readQRCode(String filePath, String charset, Map hintMap)
          throws FileNotFoundException, IOException, NotFoundException {
        BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(
            new BufferedImageLuminanceSource(
                ImageIO.read(new FileInputStream(filePath)))));
        Result qrCodeResult = new MultiFormatReader().decode(binaryBitmap, hintMap);
        return qrCodeResult.getText();
      }
    }
    

Solution 2

I now read deeper into Zxing and the following code will work with Zxing v3.2.1 (This code works without javase lib)

// Imports
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;

import com.google.zxing.BinaryBitmap;
import com.google.zxing.ChecksumException;
import com.google.zxing.FormatException;
import com.google.zxing.LuminanceSource;
import com.google.zxing.NotFoundException;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Reader;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import com.google.zxing.qrcode.QRCodeReader;

// Interesting method
public static String decodeQRImage(String path) {
    Bitmap bMap = BitmapFactory.decodeFile(path);
    String decoded = null;

    int[] intArray = new int[bMap.getWidth() * bMap.getHeight()];
    bMap.getPixels(intArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(),
            bMap.getHeight());
    LuminanceSource source = new RGBLuminanceSource(bMap.getWidth(),
            bMap.getHeight(), intArray);
    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

    Reader reader = new QRCodeReader();
    try {
        Result result = reader.decode(bitmap);
        decoded = result.getText();
    } catch (NotFoundException e) {
        e.printStackTrace();
    } catch (ChecksumException e) {
        e.printStackTrace();
    } catch (FormatException e) {
        e.printStackTrace();
    }
    return decoded;
}

Solution 3

This code works fine for me. Hope it helps just import the necessary packages and it should work

public class QR_Reader extends JFrame implements Runnable, ThreadFactory {

private static final long serialVersionUID = 6441489157408381878L;

private Executor executor = Executors.newSingleThreadExecutor(this);

private Webcam webcam = null;
private WebcamPanel panel = null;
String s;

public QR_Reader() {
    super();
    setLayout(new FlowLayout());
    setTitle("Reading QR Code");
    Dimension size = WebcamResolution.QVGA.getSize();
    webcam = Webcam.getWebcams().get(0);
    webcam.setViewSize(size);
    panel = new WebcamPanel(webcam);
    panel.setPreferredSize(size);
    add(panel);
    pack();
    setVisible(true);
    setResizable(false);
    executor.execute(this);
}
@Override
public void run() {

    do {
        try {
            Thread.sleep(100);
        } catch (InterruptedException e) {
            e.printStackTrace();
        }

        Result result = null;
        BufferedImage image = null;

        if (webcam.isOpen()) {

            if ((image = webcam.getImage()) == null) {
                continue;
            }

            LuminanceSource source = new BufferedImageLuminanceSource(image);
            BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

            try {
                result = new MultiFormatReader().decode(bitmap);
            } catch (NotFoundException e) {
                // fall thru, it means there is no QR code in image
            }
        }

        if (result != null) {
            String time_then=result.getText();  //this is the text extracted from QR CODE
            webcam.close();
            this.setVisible(false);
            this.dispose();
            try {
                new Compare().C_Main(time_then);
            } catch (ParseException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }
        }

    } while (true);
}

@Override
public Thread newThread(Runnable r) {
    Thread t = new Thread(r, "example-runner");
    t.setDaemon(true);
    return t;
}

void QRC_Main() {
    new QR_Reader();
}
}
Share:
29,511
Admin
Author by

Admin

Updated on January 23, 2021

Comments

  • Admin
    Admin over 3 years

    First of all, I read through all those topics how to use Zxing in Java but always got errors with missing com.google.zxing.client.j2se.* (I loaded the zxing core-3.2.1.jar in eclipse and all other zxing packages work unless j2se) or just found solutions for creating qr images...

    My aim is to write one single method which gets an image file finds the qr code in this image, decodes the qr code and returns the string, basically it should be something like the following:

    import com.google.zxing.*;
    
    public class QRCode {
    
        /*
         * ...
         */
    
        public String getDecodedString(SomeStandardImageType photo){
            // detect the qr code in a photo
            // create qr image from detected area in photo
            // decode the new created qr image and return the string
            return "This is the decoded dataString from the qr code in the photo";
        }
    
    }
    

    To sum up the method should get an image file like the following

    enter image description here

    and should return the url or if failed just "".

    The code should be compatible with Zxing 3.2.1.

    Edit: The question is solved. For others who are interested in this I want to say that it is important to add both external jars core-3.2.1.jar and javase-3.2.1.jar to external jars. The answer by me works without the latter but depends on android image libs.

  • Admin
    Admin about 8 years
    Thanks for your answer but atleast BufferedImageLuminanceSource is not available for me in Zxing 3.2.1
  • danish.ahmad
    danish.ahmad about 8 years
    I used this jar for qrcode reading and [that one] (java2s.com/Code/Jar/w/Downloadwebcamcapture033jar.htm) for image capture with webcam. It must include all the classes
  • Admin
    Admin about 8 years
    This is version 2.2.0 not 3.2.1 nevertheless I appreciate your answer since you want to help. In fact on complete Stackoverflow is no working 3.2.1 version. The only working code for creating qr codes is from crunshify but I want the opposite direction...
  • Admin
    Admin about 8 years
    If there is no solution I will go with 2.2.0 but I still hope someone got the skills to write a solution for 3.2.1
  • Admin
    Admin about 8 years
    Thanks. Your code is a good base for development with eclipse since you're not using android libs. This works using Zxing 3.2.1 if also javase-3.2.1.jar is added to external jars.