Recent projects have used the generation and identification of two-dimensional codes, before contact with this piece, and then on the Internet search, found that there are a lot of resources in this area, especially the Google zxing to the two-dimensional code of the package, the implementation has been good, you can directly take over the reference, downloaded their source code, only made a little change, is in the demo to increase the long according to the function of recognition, online although there are long by the identification of the demo, but a lot of download down but can not run, and then summed up, added in the following demo.
The main class for this demo is described below
public class Barcodetestactivity extends activity {private TextView Resulttextview;
Private EditText Qrstredittext;
Private ImageView Qrimgimageview;
Private String time;
Private file File = null;
@Override public void OnCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
Setcontentview (R.layout.main);
Resulttextview = (TextView) This.findviewbyid (R.id.tv_scan_result);
Qrstredittext = (edittext) This.findviewbyid (r.id.et_qr_string);
Qrimgimageview = (ImageView) This.findviewbyid (r.id.iv_qr_image);
Button Scanbarcodebutton = (button) This.findviewbyid (R.id.btn_scan_barcode); Scanbarcodebutton.setonclicklistener (New Onclicklistener () {@Override public void OnClick (View v) {//Open Scan Interface Scan barcode or two-dimensional
Code Intent opencameraintent = new Intent (barcodetestactivity.this,captureactivity.class);
Startactivityforresult (opencameraintent, 0);
}
}); Qrimgimageview.setonlongclicklistener (New Onlongclicklistener () {@Override public boolEan Onlongclick (View v) {//long by recognition two-dimensional code savecurrentimage ();
return true;
}
});
Button Generateqrcodebutton = (button) This.findviewbyid (R.id.btn_add_qrcode); Generateqrcodebutton.setonclicklistener (New Onclicklistener () {@Override public void OnClick (View v) {try {String
contentstring = Qrstredittext.gettext (). toString (); if (!contentstring.equals (")) {//The two-dimensional code picture is generated from the string and displayed on the interface, the second parameter is the size of the picture (350*350) Bitmap Qrcodebitmap =
Encodinghandler.createqrcode (contentstring, 350);
Qrimgimageview.setimagebitmap (QRCODEBITMAP);
}else {//Hint text cannot be empty toast.maketext (barcodetestactivity.this, "text can not is empty", Toast.length_short). Show ();
The catch (Writerexception e) {//TODO auto-generated catch block E.printstacktrace ();
}
}
}); //This method the status bar is blank, the information in the status bar is not displayed private void Savecurrentimage () {//Get the size of the current screen int width = GetWindow (). Getdecorview
(). Getrootview (). GetWidth ();
int height = GetWindow (). Getdecorview (). Getrootview (). GetHeight (); Generate the same sizePicture Bitmap Tembitmap = bitmap.createbitmap (width, height, Bitmap.Config.ARGB_8888);
Locate the root layout of the current page view view = GetWindow (). Getdecorview (). Getrootview ();
Set Cache view.setdrawingcacheenabled (TRUE);
View.builddrawingcache ();
Gets the picture of the current screen from the cache and creates a drawingcache copy, because the Drawingcache bitmap is recycled after it is disabled tembitmap = View.getdrawingcache ();
SimpleDateFormat df = new SimpleDateFormat ("Yyyymmddhhmmss");
Time = Df.format (new Date ()); if (Environment.MEDIA_MOUNTED.equals (Environment.getexternalstoragestate ())) {file = new file (
Environment.getexternalstoragedirectory (). GetAbsolutePath () + "/screen", Time + ". png");
if (!file.exists ()) {File.getparentfile (). Mkdirs ();
try {file.createnewfile ();
catch (IOException e) {//TODO auto-generated catch block E.printstacktrace ();
} FileOutputStream fos = null;
try {fos = new FileOutputStream (file);
Tembitmap.compress (Bitmap.CompressFormat.PNG, FOS); Fos.flush ();
Fos.close ();
catch (FileNotFoundException e) {e.printstacktrace ();
catch (IOException e) {//TODO auto-generated catch block E.printstacktrace (); New Thread (New Runnable () {@Override public void run () {String path = Environment.getexternalstora
Gedirectory (). GetAbsolutePath () + "/screen/" + Time + ". png";
Final result result = Parseqrcodebitmap (path); Runonuithread (New Runnable () {public void run () {if (Null!=result) {Resulttextview.settext (result.to
String ());
}else{Toast.maketext (Barcodetestactivity.this, "unrecognized", Toast.length_long). Show ();
}
}
});
}). Start ();
Disabling DRAWINGCAHCE otherwise affects performance and does not prohibit a bitmap view.setdrawingcacheenabled (false) that will cause each screenshot to be cached. }//Parse two-dimensional code picture, return results encapsulated in result object private Com.google.zxing.Result Parseqrcodebitmap (String bitmappath) {//Resolution conversion type U TF-8 Hashtable<decodehinttype, string> hints = new HASHTABLE<decodehinttype, string> ();
Hints.put (Decodehinttype.character_set, "utf-8");
Get to the picture to be resolved bitmapfactory.options Options = new Bitmapfactory.options (); If we set Injustdecodebounds to True, then Bitmapfactory.decodefile (String path, Options opt)//won't really return a bitmap to you, it will just take it wide,
Gao take back to you options.injustdecodebounds = true; At this point the Bitmap is null, after this code, Options.outwidth and Options.outheight are the widths and heights we want Bitmap Bitmap = Bitmapfactory.decodefile (
Bitmappath,options);
We now want to take out the picture of the edges (two-dimensional code picture is square) set to 400 pixels/** options.outheight = 400;
Options.outwidth = 400;
Options.injustdecodebounds = false;
Bitmap = Bitmapfactory.decodefile (Bitmappath, Options); *///above this approach, although the bitmap limit to the size we want, but did not save memory, if we want to save memory, we also need to use insimplesize this attribute options.insamplesize = Options.outheight
/400; if (options.insamplesize <= 0) {options.insamplesize = 1;//prevent its value less than or equal to 0}/** * Helper save memory Settings * option S.inpreferredconfig = Bitmap.Config.ARGB_4444; Default is Bitmap.Config.ARGb_8888 * options.inpurgeable = true;
* Options.ininputshareable = true;
* * Options.injustdecodebounds = false;
Bitmap = Bitmapfactory.decodefile (Bitmappath, Options);
Creates a new Rgbluminancesource object that passes bitmap pictures to this object Rgbluminancesource Rgbluminancesource = new Rgbluminancesource (bitmap);
Converts a picture into a binary picture binarybitmap Binarybitmap = new Binarybitmap (new Hybridbinarizer (Rgbluminancesource));
Initialize Parse object Qrcodereader reader = new Qrcodereader ();
Start parsing result result = NULL;
try {result = Reader.decode (Binarybitmap, hints);
catch (Exception e) {//Todo:handle Exception} return result; @Override protected void Onactivityresult (int requestcode, int resultcode, Intent data) {Super.onactivityresult (re
Questcode, ResultCode, data);
Process scan results (displayed on the interface) if (ResultCode = = RESULT_OK) {Bundle Bundle = Data.getextras ();
String Scanresult = bundle.getstring ("result");
Resulttextview.settext (Scanresult); }
}
}
And then long by the recognition of the two-dimensional code called Rgbluminancesource this class
public class Rgbluminancesource extends Luminancesource {
private byte bitmappixels[];
Protected Rgbluminancesource (Bitmap Bitmap) {
super (Bitmap.getwidth (), Bitmap.getheight ());
First, to get the pixel array content of the picture
int[] data = new Int[bitmap.getwidth () * bitmap.getheight ()];
This.bitmappixels = new Byte[bitmap.getwidth () * bitmap.getheight ()];
Bitmap.getpixels (data, 0, getwidth (), 0, 0, getwidth (), getheight ());
Converts an array of int to a byte array, that is, the blue value part of the pixel value as the discrimination content for
(int i = 0; i < data.length; i++) {
this.bitmappixels[i] = (byte) d Ata[i];
}
@Override public
byte[] Getmatrix () {
//returns our generated pixel data return
bitmappixels;
}
@Override public
byte[] GetRow (int y, byte[] row) {
//here to get the pixel data for the specified row
system.arraycopy (bitmappixels, Y * GetWidth (), row, 0, getwidth ());
return row;
}
Camera recognition two-dimensional code called Captureactivity this class
public class Captureactivity extends activity implements Callback {private Captureactivityhandler handler;
Private Viewfinderview Viewfinderview;
Private Boolean hassurface;
Private vector<barcodeformat> decodeformats;
Private String CharacterSet;
Private Inactivitytimer Inactivitytimer;
Private MediaPlayer MediaPlayer;
Private Boolean playbeep;
Private static final float beep_volume = 0.10f;
private Boolean vibrate;
Private Button Cancelscanbutton; /** called the activity is a.
* * @Override public void onCreate (Bundle savedinstancestate) {super.oncreate (savedinstancestate);
Setcontentview (R.layout.camera);
Cameramanager.init (Getapplication ());
Viewfinderview = (Viewfinderview) Findviewbyid (R.id.viewfinder_view);
Cancelscanbutton = (Button) This.findviewbyid (R.id.btn_cancel_scan);
Hassurface = false;
Inactivitytimer = new Inactivitytimer (this);
} @Override protected void Onresume () {super.onresume (); Surfaceview Surfaceview = (Surfaceview) Findviewbyid (R.id.preview_view);
Surfaceholder Surfaceholder = Surfaceview.getholder ();
if (hassurface) {Initcamera (Surfaceholder);
else {surfaceholder.addcallback (this);
Surfaceholder.settype (surfaceholder.surface_type_push_buffers);
} decodeformats = null;
CharacterSet = null;
Playbeep = true;
Audiomanager Audioservice = (audiomanager) getsystemservice (Audio_service);
if (Audioservice.getringermode ()!= audiomanager.ringer_mode_normal) {playbeep = false;
} initbeepsound ();
vibrate = true; Quit the Scan view Cancelscanbutton.setonclicklistener (new Onclicklistener () {@Override public void OnClick (View V
) {CaptureActivity.this.finish ();
}
});
} @Override protected void OnPause () {super.onpause ();
if (handler!= null) {handler.quitsynchronously ();
handler = NULL;
} cameramanager.get (). Closedriver ();
} @Override protected void OnDestroy () {Inactivitytimer.shutdown ();
Super.ondestroy (); }/** * Handler scan RESult * @param result * @param barcode/public void Handledecode (result result, Bitmap barcode) {Inactivitytimer.on
Activity ();
Playbeepsoundandvibrate ();
String resultstring = Result.gettext (); Fixme if (Resultstring.equals ("")) {//scan failed Toast.maketext (captureactivity.this, Scan failed!, Toast.length_short)
. Show ();
}else {//System.out.println ("Result:" +resultstring);
Intent resultintent = new Intent ();
Bundle Bundle = new Bundle ();
Bundle.putstring ("result", resultstring);
Resultintent.putextras (bundle);
This.setresult (RESULT_OK, resultintent);
} CaptureActivity.this.finish ();
private void Initcamera (Surfaceholder surfaceholder) {try {cameramanager.get (). Opendriver (Surfaceholder);
catch (IOException IoE) {return;
catch (RuntimeException e) {return;
} if (handler = null) {handler = new Captureactivityhandler (this, decodeformats, CharacterSet); @Override public void surfacechanged (surfaceholder holder, int format, int width,
int height) {} @Override public void surfacecreated (Surfaceholder holder) {if (!hassurface) {hassurface = tr
Ue
Initcamera (holder);
@Override public void surfacedestroyed (Surfaceholder holder) {hassurface = false;
Public Viewfinderview Getviewfinderview () {return viewfinderview;
Public Handler GetHandler () {return Handler;
public void Drawviewfinder () {viewfinderview.drawviewfinder (); private void Initbeepsound () {if (playbeep && mediaPlayer = null) {//the volume on Stream_system are not a
Djustable, and users found it//too loud,//So we-play on the music stream.
Setvolumecontrolstream (Audiomanager.stream_music);
MediaPlayer = new MediaPlayer ();
Mediaplayer.setaudiostreamtype (Audiomanager.stream_music);
Mediaplayer.setoncompletionlistener (Beeplistener);
Assetfiledescriptor file = Getresources (). OPENRAWRESOURCEFD (R.raw.beep); try {Mediaplayer.setdatasource (File.getfiledescriptor (), File.getstartoffset(), file.getlength ());
File.close ();
Mediaplayer.setvolume (Beep_volume, Beep_volume);
Mediaplayer.prepare ();
catch (IOException e) {mediaPlayer = null;
}} private static final long vibrate_duration = 200L;
private void Playbeepsoundandvibrate () {if (playbeep && mediaPlayer!= null) {Mediaplayer.start ();
} if (vibrate) {Vibrator Vibrator = (Vibrator) getsystemservice (Vibrator_service);
Vibrator.vibrate (vibrate_duration);
}/** * Beep has finished playing, rewind to queue up another one. * Private final Oncompletionlistener Beeplistener = new Oncompletionlistener () {public void oncompletion (MediaPlayer m
Ediaplayer) {mediaplayer.seekto (0);
}
}; }
The following is the master layout Mian file
<?xml version= "1.0" encoding= "Utf-8"?> <linearlayout xmlns:android= "http://schemas.android.com/apk/res/" Android "Android:layout_width=" Fill_parent "android:layout_height=" fill_parent "android:background=" @android: Color/white "android:orientation=" vertical "> <button android:id=" @+id/btn_scan_barcode "Android:layou" T_width= "Fill_parent" android:layout_height= "wrap_content" android:layout_margintop= "30DP" android:text= "Open Cam Era "/> <linearlayout android:orientation=" Horizontal "android:layout_margintop=" 10DP "Android:layout_
Width= "Fill_parent" android:layout_height= "wrap_content" > <textview android:layout_width= "wrap_content" android:layout_height= "Wrap_content" android:textcolor= "@android: Color/black" android:textsize= "18sp" Android
: text= "Scan result:"/> <textview android:id= "@+id/tv_scan_result" android:layout_width= "Fill_parent" Android:textsize= "18SP" Android:teXtcolor= "@android: Color/black" android:layout_height= "wrap_content"/> </LinearLayout> <edittext Android:id= "@+id/et_qr_string" android:layout_width= "fill_parent" android:layout_height= "Wrap_content" Android:la yout_margintop= "30DP" android:hint= "Input the text"/> <button android:id= "@+id/btn_add_qrcode" Android : layout_width= "fill_parent" android:layout_height= "wrap_content" android:text= "Generate qrcode"/> <Image View android:id= "@+id/iv_qr_image" android:layout_width= "250DP" android:layout_height= "250DP" Android:scaletyp E= "Fitxy" android:layout_margintop= "10DP" android:layout_gravity= "center"/> </LinearLayout>
For more information please download demo to see for themselves, demo solution in the vertical beat decoding the two-dimensional code is stretched phenomenon.
But I've got a problem. The scanning frame of two-dimensional code is adjusted to a large extent, the sensitivity of the scan is lowered, and the friend who wants to know
Interested can download demo take a look: Google zxing to achieve two-dimensional code generation
The above is the entire content of this article, I hope to help you learn, but also hope that we support the cloud habitat community.