Android platform QR code generation, scanning & amp; recognition, android platform

Source: Internet
Author: User

QR code generation, scanning, and identification for Android platforms
1. The past and present of the QR code

"Two-dimensional bar code/two-dimensional code (2-dimen1_bar code) is to use a specific geometric image on the plane according to a certain law (two-dimensional direction) the distributed black and white figures record the data symbol information. In code compilation, the concept of "0" and "1" bits that constitute the computer's internal logic is cleverly used, it uses a number of ry shapes corresponding to the binary to represent the numerical value of the text. It can be automatically read by the image input device or the photoelectric scanning device for automatic information processing: it has some commonalities of bar code technology: each code system has its own character set, each character occupies a certain width, and has a certain verification function. It also supports automatic identification of different rows of information and processing of graphical rotation changes. [1]"

The above is the explanation of Baidu encyclopedia. Since there is a QR code, there must be a QR code.

One-dimensional code. The most common is the bar code behind food & books.

Barcode originated in 1940s, and later in 1970 UPC code was invented, and began to be widely used in food packaging.

For details, refer to the one-dimensional code of Baidu encyclopedia.

In fact, two-dimensional codes are essentially similar to one-dimensional arrays and two-dimensional arrays.

2. java support library for QR codes

To allow java or android to easily inherit the bar code function, google developed a zxing Library:

Https://github.com/zxing/zxing

 

3. Generate a QR code
Public class EncodeThread {public static void encode (final String url, final int width, final int height, final EncodeResult result) {if (result = null) {return ;} if (TextUtils. isEmpty (url) {result. onEncodeResult (null); return;} new Thread () {@ Override public void run () {try {MultiFormatWriter writer = new MultiFormatWriter (); Hashtable <EncodeHintType, string> hints = new Hashtable <> (); hints. put (EncodeHintType. CHARACTER_SET, "UTF-8"); BitMatrix bitMatrix = writer. encode (url, BarcodeFormat. QR_CODE, width, height, hints); Bitmap bitmap = parseBitMatrix (bitMatrix); result. onEncodeResult (bitmap); return;} catch (WriterException e) {e. printStackTrace ();} result. onEncodeResult (null );}}. start ();}/*** generate the QR code content <br> ** @ param matrix * @ return */public static Bitmap parseBitMatrix (BitMatrix matrix) {final int QR_WIDTH = matrix. getWidth (); final int QR_HEIGHT = matrix. getHeight (); int [] pixels = new int [QR_WIDTH * QR_HEIGHT]; // this we using qrcode algorithm for (int y = 0; y <QR_HEIGHT; y ++) {for (int x = 0; x <QR_WIDTH; x ++) {if (matrix. get (x, y) {pixels [y * QR_WIDTH + x] = 0xff000000;} else {pixels [y * QR_WIDTH + x] = 0 xffffffff ;}}} bitmap bitmap = Bitmap. createBitmap (QR_WIDTH, QR_HEIGHT, Bitmap. config. ARGB_8888); bitmap. setPixels (pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT); return bitmap;} public interface EncodeResult {void onEncodeResult (Bitmap bitmap );}}

Zxing supports many bar code formats: QR_CODE is used here. That is, our common QR code.

Let's analyze this code first:

 MultiFormatWriter writer = new MultiFormatWriter();

This is a tool class that writes all the supported writes in it.

public BitMatrix encode(String contents,                          BarcodeFormat format,                          int width, int height,                          Map<EncodeHintType,?> hints) throws WriterException {    Writer writer;    switch (format) {      case EAN_8:        writer = new EAN8Writer();        break;      case UPC_E:        writer = new UPCEWriter();        break;      case EAN_13:        writer = new EAN13Writer();        break;      case UPC_A:        writer = new UPCAWriter();        break;      case QR_CODE:        writer = new QRCodeWriter();        break;      case CODE_39:        writer = new Code39Writer();        break;      case CODE_93:        writer = new Code93Writer();        break;      case CODE_128:        writer = new Code128Writer();        break;      case ITF:        writer = new ITFWriter();        break;      case PDF_417:        writer = new PDF417Writer();        break;      case CODABAR:        writer = new CodaBarWriter();        break;      case DATA_MATRIX:        writer = new DataMatrixWriter();        break;      case AZTEC:        writer = new AztecWriter();        break;      default:        throw new IllegalArgumentException("No encoder available for format " + format);    }    return writer.encode(contents, format, width, height, hints);  }

This is the latest officially supported format. For details, see the supported formats in the imported jar.

For bitmatrix results, you can touch an algorithm to set each vertex to white or black.

Create an image of the QR code.

4. Identify the QR code

How to identify a QR code from an image:

Public class ReDecodeThread {public static void encode (final Bitmap bitmap, final ReDecodeThreadResult listener) {if (listener = null) {return;} if (bitmap = null) {listener. onReDecodeResult (null); return;} new Thread () {@ Override public void run () {try {MultiFormatReader multiFormatReader = new MultiFormatReader (); BitmapLuminanceSource source = new BitmapLuminanceSource (bitmap ); binaryBitmap bitmap1 = new BinaryBitmap (new HybridBinarizer (source); Result result1 = multiFormatReader. decode (bitmap1); listener. onReDecodeResult (result1.getText (); return;} catch (NotFoundException e) {e. printStackTrace ();} listener. onReDecodeResult (null );}}. start () ;}public interface ReDecodeThreadResult {void onReDecodeResult (String url );}}View Code

The process is also very simple. Using MultiFormatReader to analyze images does not require the barcode format of missing images.

If the source code is analyzed, the reader of each format is used for analysis until appropriate information is found.

Of course, Bitmap can be converted into Bitmatrix and then analyzed.

Public final class extends LuminanceSource {private final byte [] luminances; public BitmapLuminanceSource (String path) throws consume {this (loadBitmap (path);} public BitmapLuminanceSource (Bitmap bitmap) {super (bitmap. getWidth (), bitmap. getHeight (); int width = bitmap. getWidth (); int height = bitmap. getHeight (); int [] pixels = new int [width * height]; bitmap. getPixels (pixels, 0, width, 0, 0, width, height); // In order to measure pure decoding speed, we convert the entire image // to a greyscale array // up front, which is the same as the Y channel of the // YUVLuminanceSource in the real app. luminances = new byte [width * height]; for (int y = 0; y Scanning the QR code is actually only one step more than above. It is to directly convert what camera gets and then identify it.

  public void requestPreviewFrame(Handler handler, int message) {    if (camera != null && previewing) {      previewCallback.setHandler(handler, message);      if (useOneShotPreviewCallback) {        camera.setOneShotPreviewCallback(previewCallback);      } else {        camera.setPreviewCallback(previewCallback);      }    }  }

First, put the data previewed by camera into previewCallback.

final class PreviewCallback implements Camera.PreviewCallback
public void onPreviewFrame(byte[] data, Camera camera) {    Point cameraResolution = configManager.getCameraResolution();    if (!useOneShotPreviewCallback) {      camera.setPreviewCallback(null);    }    if (previewHandler != null) {      Message message = previewHandler.obtainMessage(previewMessage, cameraResolution.x,          cameraResolution.y, data);      message.sendToTarget();      previewHandler = null;    } else {      Log.d(TAG, "Got preview callback, but no handler for it");    }  }

We can see that the Preview data is passed back and then passed in handler mode.

Where data is received:

  @Override  public void handleMessage(Message message) {    switch (message.what) {      case R.id.decode:        //Log.d(TAG, "Got decode message");        decode((byte[]) message.obj, message.arg1, message.arg2);        break;      case R.id.quit:        Looper.myLooper().quit();        break;    }  }

Then decode data

private void decode(byte[] data, int width, int height) {    long start = System.currentTimeMillis();    Result rawResult = null;        //modify here    byte[] rotatedData = new byte[data.length];    for (int y = 0; y < height; y++) {        for (int x = 0; x < width; x++)            rotatedData[x * height + height - y - 1] = data[x + y * width];    }    int tmp = width; // Here we are swapping, that's the difference to #11    width = height;    height = tmp;        PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(rotatedData, width, height);    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));    try {      rawResult = multiFormatReader.decodeWithState(bitmap);    } catch (ReaderException re) {      // continue    } finally {      multiFormatReader.reset();    }    if (rawResult != null) {      long end = System.currentTimeMillis();      Log.d(TAG, "Found barcode (" + (end - start) + " ms):\n" + rawResult.toString());      Message message = Message.obtain(activity.getHandler(), R.id.decode_succeeded, rawResult);      Bundle bundle = new Bundle();      bundle.putParcelable(DecodeThread.BARCODE_BITMAP, source.renderCroppedGreyscaleBitmap());      message.setData(bundle);      //Log.d(TAG, "Sending decode succeeded message...");      message.sendToTarget();    } else {      Message message = Message.obtain(activity.getHandler(), R.id.decode_failed);      message.sendToTarget();    }  }

After the image on camera is converted into a BinaryBitmap, the rest is the same for image recognition.

PlanarYUVLuminanceSource source = CameraManager.get().buildLuminanceSource(rotatedData, width, height);    BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));

Refer:

Http://www.cnblogs.com/weixing/archive/2013/08/28/3287120.html

Related Article

Contact Us

The content source of this page is from Internet, which doesn't represent Alibaba Cloud's opinion; products and services mentioned on that page don't have any relationship with Alibaba Cloud. If the content of the page makes you feel confusing, please write us an email, we will handle the problem within 5 days after receiving your email.

If you find any instances of plagiarism from the community, please send an email to: info-contact@alibabacloud.com and provide relevant evidence. A staff member will contact you within 5 working days.

A Free Trial That Lets You Build Big!

Start building with 50+ products and up to 12 months usage for Elastic Compute Service

  • Sales Support

    1 on 1 presale consultation

  • After-Sales Support

    24/7 Technical Support 6 Free Tickets per Quarter Faster Response

  • Alibaba Cloud offers highly flexible support services tailored to meet your exact needs.