查找图片中的二维码并使用Zxing解码

Find QR code in image and decode it using Zxing

首先,我通读了所有关于如何在 Java 中使用 Zxing 的主题,但总是出现缺少 com.google.zxing.client.j2se.* 的错误(我加载了 zxing core-3.2.1.jar 在 eclipse 和所有其他 zxing 包中工作,除非 j2se) 或者只是找到创建 qr 图像的解决方案...

我的目标是编写一个获取图像文件的单一方法,在该图像中找到二维码,解码二维码和 returns 字符串,基本上它应该像下面这样:

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

}

总结该方法应该得到如下图像文件

并且应该 return url 或者如果失败只是 "".

代码应与 Zxing 3.2.1 兼容。

编辑:问题已解决。对于对此感兴趣的其他人,我想说将外部罐子 core-3.2.1.jar javase-3.2.1.jar 添加到外部罐子很重要。我的答案在没有后者的情况下有效,但取决于 android 图像库。

这段代码对我来说很好用。希望它有助于导入必要的包并且它应该工作

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

我现在更深入地阅读 Zxing,以下代码将适用于 Zxing v3.2.1(此代码无需 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;
}

这里是创建二维码和从二维码读取消息的代码

  1. 您需要构建 zxing 库

  2. 主要描述二维码创建和二维码提取

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