【网学网提醒】:以下是网学会员为您推荐的在Android上使用ZXing识别条码,希望本篇文章对您学习有所帮助。
在Android上使用ZXing识别条码/二维码越来越多的手机具备自动对焦的拍摄功能,这也意味着这些手机可以具备条码扫描的功能.......手机具备条码扫描的功能,可以优化购物流程,快速存储电子名片(二维码)等。本文使用ZXing1.6实现条码/二维码识别。ZXing是个很经典的条码/二维码识别的开源类库,longlongago,就有开发者在J2ME上使用ZXing了,不过要支持JSR-234规范(自动对焦)的手机才能发挥其威力,而目前已经有不少Android手机具备自动对焦的功能。本文代码运行的结果如下,使用91手机助手截图时,无法截取SurfaceView的实时图像:
本文使用了ZXing1.6的core,即把\zxing-1.6\core\下的src复制覆盖工程的src;另外还要使用到\zxing-1.6\android\下的PlanarYUVLuminanceSource.java。PS:\zxing-1.6\android\是BarcodeScanner的源码,本文
程序相当于BarcodeScanner的精简版,只保留最基本的识别功能。源码目录结果如下图,ChecksumException.java下面还有很多源文件,截图尚未列出:
main.xml源码如下,main.xml必须要用到FrameLayout才能重叠控件实现“范围框”的效果:viewplaincopytoclipboardprint?
android:layout_width="wrap_content"android:layout_below="@+id/centerView"android:layout_height="wrap_content"android:text="Scanning..."android:id="@+id/txtScanResult"android:textColor="#FF000000"> rVertical="true"android:layout_centerHorizontal="true"android:layout_width="300dip"android:background="#55FF6666"android:id="@+id/centerView"android:layout_height="180dip">testCamera.java是主类,负责控制Camera和对图像做解码,源码如下:viewplaincopytoclipboardprint?packagecom.testCamera;importjava.util.Timer;importjava.util.TimerTask;importcom.google.zxing.BinaryBitmap;importcom.google.zxing.MultiFormatReader;importcom.google.zxing.Result;importcom.google.zxing.Android.PlanarYUVLuminanceSource;importcom.google.zxingmon.HybridBinarizer;importandroid.app.Activity;importandroid.graphics.Bitmap;importandroid.hardware.Camera;importandroid.os.Bundle;importandroid.view.SurfaceView;importandroid.view.View;importandroid.widget.ImageView;
importandroid.widget.TextView;publicclasstestCameraextendsActivity{/**Calledwhentheactivityisfirstcreated.*/privateSurfaceViewsfvCamera;privateSFHCamerasfhCamera;privateImageViewimgView;privateViewcenterView;privateTextViewtxtScanResult;privateTimermTimer;privateMyTimerTaskmTimerTask;//按照标准HVGAfinalstaticintwidth=480;finalstaticintheight=320;intdstLeft,dstTop,dstWidth,dstHeight;@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);this.setTitle("Android条码/二维码识别Demo-----hellogv");imgView=(ImageView)this.findViewById(R.id.ImageView01);centerView=(View)this.findViewById(R.id.centerView);sfvCamera=(SurfaceView)this.findViewById(R.id.sfvCamera);sfhCamera=newSFHCamera(sfvCamera.getHolder(),width,height,previewCallback);txtScanResult=(TextView)this.findViewById(R.id.txtScanResult);//初始化定时器mTimer=newTimer();mTimerTask=newMyTimerTask();mTimer.schedule(mTimerTask,0,80);}classMyTimerTaskextendsTimerTask{@Overridepublicvoidrun(){if(dstLeft==0){//只赋值一次dstLeft=centerView.getLeft()*width/getWindowManager().getDefaultDisplay().getWidth();dstTop=centerView.getTop()*height/getWindowManager().getDefaultDisplay().getHeight();dstWidth=(centerView.getRight()-centerView.getLeft())*width/getWindowManager().getDefaultDisplay().getWidth();dstHeight=(centerView.getBottom()-centerView.getTop())*height/getWindowManager().getDefaultDisplay().getHeight();}
sfhCamera.AutoFocusAndPreviewCallback();}}/***自动对焦后输出图片*/privateCamera.PreviewCallbackpreviewCallback=newCamera.PreviewCallback(){@OverridepublicvoidonPreviewFrame(byte[]data,Cameraarg1){//取得指定范围的帧的数据PlanarYUVLuminanceSo
urcesource=newPlanarYUVLuminanceSource(data,width,height,dstLeft,dstTop,dstWidth,dstHeight);//取得灰度图BitmapmBitmap=source.renderCroppedGreyscaleBitmap();//显示灰度图imgView.setImageBitmap(mBitmap);BinaryBitmapbitmap=newBinaryBitmap(newHybridBinarizer(source));MultiFormatReaderreader=newMultiFormatReader();try{Resultresult=reader.decode(bitmap);StringstrResult="BarcodeFormat:"+result.getBarcodeFormat().toString()+"text:"+result.getText();txtScanResult.setText(strResult);}catch(Exceptione){txtScanResult.setText("Scanning");}}};}packagecom.testCamera;importjava.util.Timer;importjava.util.TimerTask;importcom.google.zxing.BinaryBitmap;importcom.google.zxing.MultiFormatReader;importcom.google.zxing.Result;importcom.google.zxing.Android.PlanarYUVLuminanceSource;importcom.google.zxingmon.HybridBinarizer;importandroid.app.Activity;importandroid.graphics.Bitmap;importandroid.hardware.Camera;importandroid.os.Bundle;importandroid.view.SurfaceView;importandroid.view.View;
importandroid.widget.ImageView;importandroid.widget.TextView;publicclasstestCameraextendsActivity{/**Calledwhentheactivityisfirstcreated.*/privateSurfaceViewsfvCamera;privateSFHCamerasfhCamera;privateImageViewimgView;privateViewcenterView;privateTextViewtxtScanResult;privateTimermTimer;privateMyTimerTaskmTimerTask;//按照标准HVGAfinalstaticintwidth=480;finalstaticintheight=320;intdstLeft,dstTop,dstWidth,dstHeight;@OverridepublicvoidonCreate(BundlesavedInstanceState){super.onCreate(savedInstanceState);setContentView(R.layout.main);this.setTitle("Android条码/二维码识别Demo-----hellogv");imgView=(ImageView)this.findViewById(R.id.ImageView01);centerView=(View)this.findViewById(R.id.centerView);sfvCamera=(SurfaceView)this.findViewById(R.id.sfvCamera);sfhCamera=newSFHCamera(sfvCamera.getHolder(),width,height,previewCallback);txtScanResult=(TextView)this.findViewById(R.id.txtScanResult);//初始化定时器mTimer=newTimer();mTimerTask=newMyTimerTask();mTimer.schedule(mTimerTask,0,80);}classMyTimerTaskextendsTimerTask{@Overridepublicvoidrun(){if(dstLeft==0){//只赋值一次dstLeft=centerView.getLeft()*width/getWindowManager().getDefaultDisplay().getWidth();dstTop=centerView.getTop()*height/getWindowManager().getDefaultDisplay().getHeight();dstWidth=(centerView.getRight()-centerView.getLeft())*width/getWindowManager().getDefaultDisplay().getWidth();dstHeight=(centerView.getBottom()-centerView.getTop())*height/getWindowManager().getDefaultDisplay().getHeight();
}sfhCamera.AutoFocusAndPreviewCallback();}}/***自动对焦后输出图片*/privateCamera.PreviewCallbackpreviewCallback=newCamera.PreviewCallback(){@OverridepublicvoidonPreviewFrame(byte[]data,Cameraarg1){//取得指定范围的帧的数据PlanarYUVLuminanceS
ourcesource=newPlanarYUVLuminanceSource(data,width,height,dstLeft,dstTop,dstWidth,dstHeight);//取得灰度图BitmapmBitmap=source.renderCroppedGreyscaleBitmap();//显示灰度图imgView.setImageBitmap(mBitmap);BinaryBitmapbitmap=newBinaryBitmap(newHybridBinarizer(source));MultiFormatReaderreader=newMultiFormatReader();try{Resultresult=reader.decode(bitmap);StringstrResult="BarcodeFormat:"+result.getBarcodeFormat().toString()+"text:"+result.getText();txtScanResult.setText(strResult);}catch(Exceptione){txtScanResult.setText("Scanning");}}};}SFHCamera.java是Camera控制类,源码如下:viewplaincopytoclipboardprint?packagecom.testCamera;importjava.io.IOException;importandroid.graphics.PixelFormat;importandroid.hardware.Camera;importandroid.util.Log;importandroid.view.SurfaceHolder;publicclassSFHCameraimplementsSurfaceHolder.Callback{privateSurfaceHolderholder=null;privateCameramCamera;
privateintwidth,height;privateCamera.PreviewCallbackpreviewCallback;publicSFHCamera(SurfaceHolderholder,intw,inth,Camera.PreviewCallbackpreviewCallback){this.holder=holder;this.holder.addCallback(this);this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);width=w;height=h;this.previewCallback=previewCallback;}@OverridepublicvoidsurfaceChanged(SurfaceHolderarg0,intarg1,intarg2,intarg3){Camera.Parametersparameters=mCamera.getParameters();parameters.setPreviewSize(width,height);//设置尺寸parameters.setPictureFormat(PixelFormat.JPEG);mCamera.setParameters(parameters);mCamera.startPreview();//开始预览Log.e("Camera","surfaceChanged");}@OverridepublicvoidsurfaceCreated(SurfaceHolderarg0){mCamera=Camera.open();//启动服务try{mCamera.setPreviewDisplay(holder);//设置预览Log.e("Camera","surfaceCreated");}catch(IOExceptione){mCamera.release();//释放mCamera=null;}}@OverridepublicvoidsurfaceDestroyed(SurfaceHolderarg0){mCamera.setPreviewCallback(null);mCamera.stopPreview();//停止预览mCamera=null;Log.e("Camera","surfaceDestroyed");}/***自动对焦并回调Camera.PreviewCallback*/
publicvoidAutoFocusAndPreviewCallback(){if(mCamera!=null)mCamera.autoFocus(mAutoFocusCallBack);}/***自动对焦*/privateCamera.AutoFocusCallbackCamera.AutoFocusCallback(){
mAutoFocusCallBack
=
new
@OverridepublicvoidonAutoFocus(booleansuccess,Cameracamera){if(success){//对焦成功,回调Camera.PreviewCallbackmCamera.setOneShotPreviewCallback(previewCallback);}}};
}packagecom.testCamera;importjava.io.IOException;importandroid.graphics.PixelFormat;importandroid.hardware.Camera;importandroid.util.Log;importandroid.view.SurfaceHolder;publicclassSFHCameraimplementsSurfaceHolder.Callback{privateSurfaceHolderholder=null;privateCameramCamera;privateintwidth,height;privateCamera.PreviewCallbackpreviewCallback;publicSFHCamera(SurfaceH
olderholder,intw,inth,Camera.PreviewCallbackpreviewCallback){this.holder=holder;this.holder.addCallback(this);this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);width=w;height=h;this.previewCallback=previewCallback;}
@OverridepublicvoidsurfaceChanged(SurfaceHolderarg0,intarg1,intarg2,intarg3){Camera.Parametersparameters=mCamera.getParameters();parameters.setPreviewSize(width,height);//设置尺寸parameters.setPictureFormat(PixelFormat.JPEG);mCamera.setParameters(parameters);mCamera.startPreview();//开始预览Log.e("Camera","surfaceChanged");}@OverridepublicvoidsurfaceCreated(SurfaceHolderarg0){mCamera=Camera.open();//启动服务try{mCamera.setPreviewDisplay(holder);//设置预览Log.e("Camera","surfaceCreated");}catch(IOExceptione){mCamera.release();//释放mCamera=null;}}@OverridepublicvoidsurfaceDestroyed(SurfaceHolderarg0){mCamera.setPreviewCallback(null);mCamera.stopPreview();//停止预览mCamera=null;Log.e("Camera","surfaceDestroyed");}/***自动对焦并回调Camera.PreviewCallback*/publicvoidAutoFocusAndPreviewCallback(){if(mCamera!=null)mCamera.autoFocus(mAutoFocusCallBack);}/***自动对焦*/privateCamera.AutoFocusCallbackCamera.AutoFocusCallback(){@Override
mAutoFocusCallBack
=
new
publicvoidonAutoFocus(booleansuccess,Cameracamera){if(success){//对焦成功,回调Camera.PreviewCallbackmCamera.setOneShotPreviewCallback(previewCallback);}}};
}
其中testCamera.java的Camera.PreviewCallbackpreviewCallback是整个程序的逻辑核心,作为回调函数给SFHCamera.java的内部Camera类调用。