1. 程式人生 > >zxing二維碼識別Helper類

zxing二維碼識別Helper類

封裝成Helper類,特此記載,也希望能幫助到後來者

定義了一個回撥介面用於解碼後輸出結果,運行於新執行緒,如要進行UI操作自行呼叫Handler介面

public class CameraDecodeHelper implements SurfaceHolder.Callback, PreviewCallback {
	// 回撥介面
	public interface Callback {
		public void onResult(String reslut, String barFormat);
	}

	/**
	 * 自動對焦
	 */
	private Camera.AutoFocusCallback mAutoFocusCallBack = new Camera.AutoFocusCallback() {

		@Override
		public void onAutoFocus(boolean success, Camera camera) {
			if (success) { // 對焦成功,回撥Camera.PreviewCallback
				mCamera.setOneShotPreviewCallback(previewCallback);
			}
		}
	};

	// 執行自動對焦後解碼條碼和二維碼
	private Camera.PreviewCallback previewCallback = new Camera.PreviewCallback() {
		@Override
		public void onPreviewFrame(final byte[] data, Camera arg1) {
			// 如果是豎屏則旋轉取得的對焦結果
			new Thread(new Runnable() {
				
				@Override
				public void run() {
					// TODO 自動生成的方法存根
					Decode(data);
				}
			}).start();
			

		}
	};
	
	private void Decode(byte[] data){
		if (shuflag) {
			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];
			}
			data = rotatedData;
		}

		// 取得指定範圍的幀的資料

		try {
			PlanarYUVLuminanceSource source;
			source = shuflag ? new PlanarYUVLuminanceSource(data, height,
					width, 0, 0, height, width, false)
					: new PlanarYUVLuminanceSource(data, width, height, 0,
							0, width, height, false);

			BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(
					source));
			MultiFormatReader reader = new MultiFormatReader();
			Result result = reader.decode(bitmap);
			String reText = result.getText();
			String barFormat = result.getBarcodeFormat().toString();
			if (callback!=null) {
				callback.onResult(reText, barFormat);
			}
			mTimer.cancel();
		} catch (Exception e) {

		}
	}

	// 開關閃光燈
	public void setFlash() {
		if (shanflag) {
			Camera.Parameters parameter = mCamera.getParameters();
			parameter.setFlashMode(Parameters.FLASH_MODE_OFF);
			mCamera.setParameters(parameter);
			shanflag = false;
		} else {
			Camera.Parameters parameter = mCamera.getParameters();
			parameter.setFlashMode(Parameters.FLASH_MODE_TORCH);
			mCamera.setParameters(parameter);
			shanflag = true;
		}
	}

	private SurfaceHolder holder = null;
	private Camera mCamera;
	private int width = 640;
	private int height = 480;
	private Callback callback;
	private boolean shanflag = false;
	private boolean shuflag = true;
	private Timer mTimer;

	public CameraDecodeHelper(SurfaceHolder mHolder, Camera arg,
			boolean portrait, Callback c) {
		this.holder = mHolder;
		this.holder.addCallback(this);
		this.holder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
		mTimer = new Timer();
		mCamera = arg;
		callback = c;
		shuflag = portrait;
		if (shuflag) {
			mCamera.setDisplayOrientation(90);
		}
	}

	@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();// 開始預覽
	}

	@Override
	public void surfaceCreated(SurfaceHolder arg0) {
		// mCamera = Camera.open();//啟動服務
		try {
			mCamera.setPreviewDisplay(holder);// 設定預覽
			mCamera.setPreviewCallback(this);
		} catch (IOException e) {
			mCamera.release();// 釋放
			mCamera = null;
		}

	}

	@Override
	public void surfaceDestroyed(SurfaceHolder arg0) {
		mCamera.setPreviewCallback(null);
		mCamera.stopPreview();// 停止預覽
		holder.removeCallback(this);
	}

	// 啟動自動對焦並回調
	public void AutoFocusAndPreviewCallback(long when, long replay) {
		if (mCamera != null) {
			mTimer.schedule(new TimerTask() {

				@Override
				public void run() {
					// TODO 自動生成的方法存根
					mCamera.autoFocus(mAutoFocusCallBack);
				}
			}, when, replay);

		}
	}
	
	//退出
	public void exit(){
		mTimer.cancel();
	}

	@Override
	public void onPreviewFrame(final byte[] arg0, Camera arg1) {
		// TODO 自動生成的方法存根
		new Thread(new Runnable() {
			
			@Override
			public void run() {
				// TODO 自動生成的方法存根
				Decode(arg0);
			}
		}).start();
	}
}
呼叫示例如下
private void getCode(){
		//surfaceView請自行建立,相機記得在activity中開啟
decodeHelper = new CameraDecodeHelper(cview.getHolder(), camera, true, this);
//500ms後開始對焦,400ms迴圈
		decodeHelper.AutoFocusAndPreviewCallback(500, 400);
		
	}

實現介面中OnResult方法
public void onResult(final String reslut,final String barFormat) {
		new Handler().post(new Runnable() {
			
			@Override
			public void run() {
				// TODO 自動生成的方法存根
				
				alert.cancel();
				camera.setPreviewCallback(null);
Toast.makeText(ScreenNewSpecies.this,barFormat+":"+ reslut, 3000).show();

			}
		});
		
		
	}