本文来自http://blog.csdn.net/hellogv/?,引用必须注明出处! ?????? 越来越多的手机具备自动对焦的拍摄功能,这也意味着这些手机可以具备条码扫描的功能.......手机具备条码扫描的功能,可以优化购物流程,快速存储电子名片(二维码)等。 ????? 本文使用ZXing 1.6实现条码/二维码识别。ZXing是个很经典的条码/二维码识别的开源类库,long long ago,就有开发者在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的精简版,只保留最基本的识别功能。 本文源码工程的下载地址如下:http://www.pudn.com/downloads349/sourcecode/comm/android/detail1521939.html 源码目录结果如下图,ChecksumException.java下面还有很多源文件,截图尚未列出: 本文例子必须要开摄像头和自动对焦的权限,不然启动时会报异常,所用的权限如下:
?
main.xml源码如下,main.xml必须要用到FrameLayout才能重叠控件实现“范围框”的效果:
- <?xml?version="1.0"?encoding="utf-8"?>??
- <FrameLayout?android:id="@+id/FrameLayout01"??
- ????android:layout_width="fill_parent"?android:layout_height="fill_parent"??
- ????xmlns:android="http://schemas.android.com/apk/res/android">??
- ????<SurfaceView?android:layout_height="fill_parent"??
- ????????android:id="@+id/sfvCamera"?android:layout_width="fill_parent"></SurfaceView>??
- ????<RelativeLayout?android:id="@+id/RelativeLayout01"??
- ????????android:layout_height="fill_parent"?android:layout_width="fill_parent">??
- ????????<ImageView?android:id="@+id/ImageView01"??
- ????????????android:layout_height="100dip"?android:layout_width="160dip"></ImageView>??
- ????????<View?android:layout_centerVertical="true"??
- ????????????android:layout_centerHorizontal="true"?android:layout_width="300dip"??
- ????????????android:background="#55FF6666"?android:id="@+id/centerView"??
- ????????????android:layout_height="180dip"></View>??
- ????????<TextView?android:layout_centerHorizontal="true"??
- ????????????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"></TextView>??
- ????</RelativeLayout>??
- </FrameLayout>??
?
testCamera.java是主类,负责控制Camera和对图像做解码,源码如下:
- package?com.testCamera;??
- import?java.util.Timer;??
- import?java.util.TimerTask;??
- import?com.google.zxing.BinaryBitmap;??
- import?com.google.zxing.MultiFormatReader;??
- import?com.google.zxing.Result;??
- import?com.google.zxing.Android.PlanarYUVLuminanceSource;??
- import?com.google.zxing.common.HybridBinarizer;??
- import?android.app.Activity;??
- import?android.graphics.Bitmap;??
- import?android.hardware.Camera;??
- import?android.os.Bundle;??
- import?android.view.SurfaceView;??
- import?android.view.View;??
- import?android.widget.ImageView;??
- import?android.widget.TextView;??
- public?class?testCamera?extends?Activity?{??
- ????/**?Called?when?the?activity?is?first?created.?*/??
- ????private?SurfaceView?sfvCamera;??
- ????private?SFHCamera?sfhCamera;??
- ????private?ImageView?imgView;??
- ????private?View?centerView;??
- ????private?TextView?txtScanResult;??
- ????private?Timer?mTimer;??
- ????private?MyTimerTask?mTimerTask;??
- ????//?按照标准HVGA??
- ????final?static?int?width?=?480;??
- ????final?static?int?height?=?320;??
- ????int?dstLeft,?dstTop,?dstWidth,?dstHeight;??
- ????@Override??
- ????public?void?onCreate(Bundle?savedInstanceState)?{??
- ????????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?=?new?SFHCamera(sfvCamera.getHolder(),?width,?height,??
- ????????????????previewCallback);??
- ????????txtScanResult=(TextView)this.findViewById(R.id.txtScanResult);??
- ????????//?初始化定时器??
- ????????mTimer?=?new?Timer();??
- ????????mTimerTask?=?new?MyTimerTask();??
- ????????mTimer.schedule(mTimerTask,?0,?80);??
- ????}??
- ??????
- ????class?MyTimerTask?extends?TimerTask?{??
- ????????@Override??
- ????????public?void?run()?{??
- ????????????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();??
- ????????}??
- ????}??
- ????/**?
- ?????*??自动对焦后输出图片?
- ?????*/??
- ????private?Camera.PreviewCallback?previewCallback?=?new?Camera.PreviewCallback()?{??
- ????????@Override??
- ????????public?void?onPreviewFrame(byte[]?data,?Camera?arg1)?{??
- ????????????//取得指定范围的帧的数据??
- ????????????PlanarYUVLuminanceSource?source?=?new?PlanarYUVLuminanceSource(??
- ????????????????????data,?width,?height,?dstLeft,?dstTop,?dstWidth,?dstHeight);??
- ????????????//取得灰度图??
- ????????????Bitmap?mBitmap?=?source.renderCroppedGreyscaleBitmap();??
- ????????????//显示灰度图??
- ????????????imgView.setImageBitmap(mBitmap);??
- ????????????BinaryBitmap?bitmap?=?new?BinaryBitmap(new?HybridBinarizer(source));??
- ????????????MultiFormatReader?reader?=?new?MultiFormatReader();??
- ????????????try?{??
- ????????????????Result?result?=?reader.decode(bitmap);??
- ????????????????String?strResult?=?"BarcodeFormat:"??
- ????????????????????????+?result.getBarcodeFormat().toString()?+?"??text:"??
- ????????????????????????+?result.getText();??
- ????????????????txtScanResult.setText(strResult);??
- ????????????}?catch?(Exception?e)?{??
- ????????????????txtScanResult.setText("Scanning");??
- ????????????}??
- ????????}??
- ????};??
- }??
?
SFHCamera.java是Camera控制类,源码如下:
- package?com.testCamera;??
- import?java.io.IOException;??
- import?android.graphics.PixelFormat;??
- import?android.hardware.Camera;??
- import?android.util.Log;??
- import?android.view.SurfaceHolder;??
- public?class?SFHCamera?implements?SurfaceHolder.Callback{??
- ????private?SurfaceHolder?holder?=?null;??
- ????private?Camera?mCamera;??
- ????private?int?width,height;??
- ????private?Camera.PreviewCallback?previewCallback;??
- ??????
- ????public?SFHCamera(SurfaceHolder?holder,int?w,int?h,Camera.PreviewCallback?previewCallback)?{??
- ????????this.holder?=?holder;????
- ????????this.holder.addCallback(this);????
- ????????this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);??
- ????????width=w;??
- ????????height=h;??
- ????????this.previewCallback=previewCallback;??
- ????}??
- ??????
- ????@Override??
- ????public?void?surfaceChanged(SurfaceHolder?arg0,?int?arg1,?int?arg2,?int?arg3)?{??
- ????????Camera.Parameters?parameters?=?mCamera.getParameters();????
- ????????parameters.setPreviewSize(width,?height);//设置尺寸????
- ????????parameters.setPictureFormat(PixelFormat.JPEG);??
- ????????mCamera.setParameters(parameters);????
- ????????mCamera.startPreview();//开始预览??
- ????????Log.e("Camera","surfaceChanged");??
- ????}??
- ????@Override??
- ????public?void?surfaceCreated(SurfaceHolder?arg0)?{??
- ????????mCamera?=?Camera.open();//启动服务????
- ????????try?{????
- ????????????mCamera.setPreviewDisplay(holder);//设置预览???
- ????????????Log.e("Camera","surfaceCreated");??
- ????????}?catch?(IOException?e)?{????
- ????????????mCamera.release();//释放????
- ????????????mCamera?=?null;????
- ????????}??
- ??????????
- ????}??
- ????@Override??
- ????public?void?surfaceDestroyed(SurfaceHolder?arg0)?{??
- ????????mCamera.setPreviewCallback(null);??
- ????????mCamera.stopPreview();//停止预览????
- ????????mCamera?=?null;??
- ????????Log.e("Camera","surfaceDestroyed");??
- ????}??
- ????/**?
- ?????*?自动对焦并回调Camera.PreviewCallback?
- ?????*/??
- ????public?void?AutoFocusAndPreviewCallback()??
- ????{??
- ????????if(mCamera!=null)??
- ????????????mCamera.autoFocus(mAutoFocusCallBack);??
- ????}??
- ??????
- ????/**?
- ?????*?自动对焦?
- ?????*/??
- ????private?Camera.AutoFocusCallback?mAutoFocusCallBack?=?new?Camera.AutoFocusCallback()?{????
- ????????????
- ????????@Override????
- ????????public?void?onAutoFocus(boolean?success,?Camera?camera)?{????????
- ????????????if?(success)?{??//对焦成功,回调Camera.PreviewCallback??
- ????????????????mCamera.setOneShotPreviewCallback(previewCallback);???
- ????????????}????
- ????????}????
- ????};??
- ??????
- ??
- }??
?
其中testCamera.java的Camera.PreviewCallback previewCallback?是整个程序的逻辑核心,作为回调函数给SFHCamera.java的内部Camera类调用。