You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

215 lines
6.7 KiB
Java

package com.king.zxing;
import android.app.Activity;
import android.content.Context;
import android.graphics.Bitmap;
import android.graphics.BitmapFactory;
import android.graphics.Point;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.Display;
import android.view.WindowManager;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.DecodeHintType;
import com.google.zxing.Result;
import com.google.zxing.ResultPoint;
import com.google.zxing.ResultPointCallback;
import com.king.zxing.camera.CameraManager;
import java.util.Collection;
import java.util.Map;
/**
* @author <a href="mailto:jenly1314@gmail.com">Jenly</a>
*/
public class CaptureHandler extends Handler implements ResultPointCallback {
private static final String TAG = CaptureHandler.class.getSimpleName();
private final OnCaptureListener onCaptureListener;
private final DecodeThread decodeThread;
private State state;
private final CameraManager cameraManager;
private final Activity activity;
private final ViewfinderView viewfinderView;
/**
* 是否支持垂直的条形码
*/
private boolean isSupportVerticalCode;
/**
* 是否返回扫码原图
*/
private boolean isReturnBitmap;
/**
* 是否支持自动缩放
*/
private boolean isSupportAutoZoom;
/**
*
*/
private boolean isSupportLuminanceInvert;
private enum State {
PREVIEW,
SUCCESS,
DONE
}
CaptureHandler(Activity activity,ViewfinderView viewfinderView,OnCaptureListener onCaptureListener,
Collection<BarcodeFormat> decodeFormats,
Map<DecodeHintType,Object> baseHints,
String characterSet,
CameraManager cameraManager) {
this.activity = activity;
this.viewfinderView = viewfinderView;
this.onCaptureListener = onCaptureListener;
decodeThread = new DecodeThread(activity,cameraManager,this, decodeFormats, baseHints, characterSet, this);
decodeThread.start();
state = State.SUCCESS;
// Start ourselves capturing previews and decoding.
this.cameraManager = cameraManager;
cameraManager.startPreview();
restartPreviewAndDecode();
}
@Override
public void handleMessage(Message message) {
if (message.what == R.id.restart_preview) {
restartPreviewAndDecode();
} else if (message.what == R.id.decode_succeeded) {
state = State.SUCCESS;
Bundle bundle = message.getData();
Bitmap barcode = null;
float scaleFactor = 1.0f;
if (bundle != null) {
byte[] compressedBitmap = bundle.getByteArray(DecodeThread.BARCODE_BITMAP);
if (compressedBitmap != null) {
barcode = BitmapFactory.decodeByteArray(compressedBitmap, 0, compressedBitmap.length, null);
// Mutable copy:
barcode = barcode.copy(Bitmap.Config.ARGB_8888, true);
}
scaleFactor = bundle.getFloat(DecodeThread.BARCODE_SCALED_FACTOR);
}
onCaptureListener.onHandleDecode((Result) message.obj, barcode, scaleFactor);
} else if (message.what == R.id.decode_failed) {// We're decoding as fast as possible, so when one decode fails, start another.
state = State.PREVIEW;
cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
}
}
public void quitSynchronously() {
state = State.DONE;
cameraManager.stopPreview();
Message quit = Message.obtain(decodeThread.getHandler(), R.id.quit);
quit.sendToTarget();
try {
// Wait at most half a second; should be enough time, and onPause() will timeout quickly
decodeThread.join(100L);
} catch (InterruptedException e) {
// continue
}
// Be absolutely sure we don't send any queued up messages
removeMessages(R.id.decode_succeeded);
removeMessages(R.id.decode_failed);
}
public void restartPreviewAndDecode() {
if (state == State.SUCCESS) {
state = State.PREVIEW;
cameraManager.requestPreviewFrame(decodeThread.getHandler(), R.id.decode);
viewfinderView.drawViewfinder();
}
}
@Override
public void foundPossibleResultPoint(ResultPoint point) {
if(viewfinderView!=null){
ResultPoint resultPoint = transform(point);
viewfinderView.addPossibleResultPoint(resultPoint);
}
}
private boolean isScreenPortrait(Context context){
WindowManager manager = (WindowManager) context.getSystemService(Context.WINDOW_SERVICE);
Display display = manager.getDefaultDisplay();
Point screenResolution = new Point();
display.getSize(screenResolution);
return screenResolution.x < screenResolution.y;
}
/**
*
* @return
*/
private ResultPoint transform(ResultPoint originPoint) {
Point screenPoint = cameraManager.getScreenResolution();
Point cameraPoint = cameraManager.getCameraResolution();
float scaleX;
float scaleY;
float x;
float y;
if(screenPoint.x < screenPoint.y){
scaleX = 1.0f * screenPoint.x / cameraPoint.y;
scaleY = 1.0f * screenPoint.y / cameraPoint.x;
x = originPoint.getX() * scaleX - Math.max(screenPoint.x,cameraPoint.y)/2;
y = originPoint.getY() * scaleY - Math.min(screenPoint.y,cameraPoint.x)/2;
}else{
scaleX = 1.0f * screenPoint.x / cameraPoint.x;
scaleY = 1.0f * screenPoint.y / cameraPoint.y;
x = originPoint.getX() * scaleX - Math.min(screenPoint.y,cameraPoint.y)/2;
y = originPoint.getY() * scaleY - Math.max(screenPoint.x,cameraPoint.x)/2;
}
return new ResultPoint(x,y);
}
public boolean isSupportVerticalCode() {
return isSupportVerticalCode;
}
public void setSupportVerticalCode(boolean supportVerticalCode) {
isSupportVerticalCode = supportVerticalCode;
}
public boolean isReturnBitmap() {
return isReturnBitmap;
}
public void setReturnBitmap(boolean returnBitmap) {
isReturnBitmap = returnBitmap;
}
public boolean isSupportAutoZoom() {
return isSupportAutoZoom;
}
public void setSupportAutoZoom(boolean supportAutoZoom) {
isSupportAutoZoom = supportAutoZoom;
}
public boolean isSupportLuminanceInvert() {
return isSupportLuminanceInvert;
}
public void setSupportLuminanceInvert(boolean supportLuminanceInvert) {
isSupportLuminanceInvert = supportLuminanceInvert;
}
}