Android platform generates two-dimensional code and implements scan & recognition functions _android

Source: Internet
Author: User

1. The two-D code of the past life

"Two-dimensional barcode/two-D code" (2-dimensional bar code) is a Black-and-white graphic recording data symbol information distributed in a plane (two-dimensional direction) by a certain geometry. Cleverly utilizes the "0", "1" which compose the logic foundation of the computer in the Code compilation The concept of bit stream, using several geometric forms corresponding to the binary to represent literal numerical information, automatic reading through an image input device or photoelectric scanning device to realize automatic information processing: It has some common features of barcode technology: Each code system has its specific character set; Each character occupies a certain width , and has a certain calibration function. At the same time, it also has the function of automatic information recognition of different lines and the processing of the change points of graphics rotation. [1] "

The above is Baidu Encyclopedia explanation. Since there are two dimensional code, then there must be a one-dimensional code.

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

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

The specific introduction can look at Baidu encyclopedia one dimensional code.

The two-dimensional code is essentially similar to a one-dimensional code, just like a one-dimensional array and a two-dimensional array.

2. Two-D Code Java Support Library

To allow Java or Android to easily inherit barcode functionality, Google has developed a zxing library:

Https://github.com/zxing/zxing

3. Generate two dimensional code

public class Encodethread {public static void encode (final String URL, final int width, final int height, final encodere Sult result) {if (result = = null) {return;} if (Textutils.isempty (URL)) {Result.onencoderesult (null); return;} New Th
Read () {@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 ();  /** * Generates two-dimensional 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 + + +) {if (Matrix.get (x, y)) {Pixels[y * Qr_w
Idth + x] = 0xff000000;
else {Pixels[y * qr_width + x] = 0xFFFFFFFF;}}
} 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 barcode formats: We use Qr_code code here. Which is the two-dimensional code in our common micro-letters.

Let's Analyze This code first:

Multiformatwriter writer = new Multiformatwriter ();

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

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 ();
= 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 official latest supported format, specifically seen in the introduction of the jar support format.

For the results with Bitmatrix, by touching an algorithm, set each dot white, or black.

Finally, create a two-dimensional code picture.

4. Identify two dimensional code

How to identify a two-dimensional code from a picture:

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

The process is also very simple, the use of Multiformatreader to analyze the picture, here does not need a short picture of the barcode format.

If the analysis of the source code, is in turn using each format of the reader to analyze, until found appropriate.

Of course back can convert bitmap into Bitmatrix, and then analyze.

Public final class Bitmapluminancesource extends luminancesource{private final byte[] luminances, public bitmapluminance Source (String path) throws FileNotFoundException {This (LoadBitmap (path)); \ Public Bitmapluminancesource (Bitmap Bitmap {Super (Bitmap.getwidth (), Bitmap.getheight ()); int width = bitmap.getwidth (); int height = bitmap.getheight (); int[] Pi
Xels = 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 < height; y++) {int offset = y * width; for (int x = 0; x < width; + +) {int pixel = pixels[offs
ET + x];
int r = (pixel >>) & 0xFF;
int g = (pixel >> 8) & 0xFF;
int b = pixel & 0xff; if (r = = g && g = = b) {//Image is already greyscale, so pick any channel.
Luminances[offset + x] = (byte) r; 
else {//Calculate luminance cheaply, favoring green. Luminances[offset + x] = (byte) ((R + G + G + B) >> 2);} @Override public byte[] GetRow (int y, byte[] row) {if (Y < 0 | | | y >= getheight ()) {throw new Illegalargumente
Xception ("Requested row is outside the image:" + y);}
int width = getwidth ();
if (row = null | | Row.length < width) {row = new byte[width];}
System.arraycopy (luminances, y * width, row, 0, width);
return row; }//Since This class does not support cropping, the underlying byte array//already contains//exactly what the caller
is asking for, so give it to them without a copy. @Override public byte[] Getmatrix () {return luminances;} private static Bitmap LoadBitmap (String path) throws ndexception {Bitmap Bitmap = bitmapfactory.decodefile (path); if (Bitmap = null) {throw new FileNotFoundException ("could
N ' t open "+ path);}
return bitmap;  }
}

5. Scan two dimensional code

Scanning two-dimensional code, in fact, than the above only one step, is to get the things camera directly converted, and then to identify.

public void Requestpreviewframe (Handler Handler, int message) {
if (camera!= null && previewing) {
Previe Wcallback.sethandler (handler, message);
if (useoneshotpreviewcallback) {
camera.setoneshotpreviewcallback (previewcallback);
} else {
Camera.setpreviewcallback (Previewcallback);
}

First, put the camera preview data into the 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");

You can see that the data in the preview is passed back over and then handler the way out.

Where to receive data:

@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 the 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 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 {Multif
Ormatreader.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 ();}

When the picture on the camera is converted to Binarybitmap, the rest of the matter is more directly from the image recognition.

Planaryuvluminancesource Source = Cameramanager.get (). Buildluminancesource (rotateddata, width, height);
Binarybitmap bitmap = new Binarybitmap (new Hybridbinarizer (source));

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.