zxing 提供的sample都是原生camera采集摄像头数据,而android上使用UVCCamera采集摄像头的情况比较多,那么怎么在uvccamera采集到摄像头数据,并调用zxing扫码呢。直接上代码。
DecodeHandle.java
package com.baidu.idl.face.main.decode;
import android.content.Context;
import android.graphics.Bitmap;
import android.os.Bundle;
import android.os.Handler;
import android.os.HandlerThread;
import android.os.Looper;
import android.os.Message;
import android.text.TextUtils;
import android.util.Log;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.ReaderException;
import com.google.zxing.Result;
import com.google.zxing.common.HybridBinarizer;
import java.util.Arrays;
import java.util.Collection;
import java.util.Map;
import java.util.EnumMap;
import java.util.EnumSet;
public class DecodeHandler {
private final DecodeListener mListener;
private boolean isAvailable = true;
private static final int DECODE_BITMAP = 0;
private static final int DECODE_YUV = 1;
//private QrDecoder mDecoder;
private DecodeThread mDecodThread;
private int mTimeout;
Context mContext;
private int mWidth;
private int mHeight;
private final Map<DecodeHintType, Object> hints;
private Collection<BarcodeFormat> decodeFormats;
private final MultiFormatReader multiFormatReader;
public DecodeHandler(Context context, DecodeListener listener,final int width, final int height) {
mWidth = width;
mHeight = height;
mListener = listener;
mContext = context;
//mDecoder = new QrDecoder(context);
HandlerThread thread = new HandlerThread("qr_decode_thread");
thread.start();
mDecodThread = new DecodeThread(thread.getLooper());
//扫码初始化
multiFormatReader = new MultiFormatReader();
decodeFormats = EnumSet.of(BarcodeFormat.QR_CODE, BarcodeFormat.CODE_128);
hints = new EnumMap<>(DecodeHintType.class);
hints.put(DecodeHintType.POSSIBLE_FORMATS, decodeFormats);
String characterSet = "utf-8";
if (characterSet != null) {
hints.put(DecodeHintType.CHARACTER_SET, characterSet);
}
hints.put(DecodeHintType.TRY_HARDER, true);
multiFormatReader.setHints(hints);
}
public void release() {
setAvailable(false);
mDecodThread.getLooper().quit();
}
public void pushYuv(byte[] yuv) {
Log.d("MainActivity","pushYuv()");
if (isAvailable()) {
setAvailable(false);
mDecodThread.obtainMessage(DECODE_YUV, yuv).sendToTarget();
}
}
private boolean isAvailable() {
return isAvailable;
}
private void setAvailable(boolean b) {
isAvailable = b;
}
private class DecodeThread extends Handler {
DecodeThread(Looper looper) {
super(looper);
}
@Override
public void handleMessage(Message msg) {
super.handleMessage(msg);
switch (msg.what) {
case DECODE_YUV:
{
decode((byte[])msg.obj,mWidth,mHeight);
setAvailable(true);
}
break;
}
}
}
/**
* @param data A preview frame.
* @param width The width of the image.
* @param height The height of the image.
* @return A PlanarYUVLuminanceSource instance.
*/
public PlanarYUVLuminanceSource buildLuminanceSource(byte[] data, int width, int height) {
return new PlanarYUVLuminanceSource(data, width, height, 0, 0,
width, height, false);
}
/**
* @param data The YUV preview frame.
* @param width The width of the preview frame.
* @param height The height of the preview frame.
*/
private void decode(byte[] data, int width, int height) {
long start = System.currentTimeMillis();
Result rawResult = null;
PlanarYUVLuminanceSource source = buildLuminanceSource(data, width, height);
if (source != null) {
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
try {
rawResult = multiFormatReader.decodeWithState(bitmap);
BarcodeFormat format = rawResult.getBarcodeFormat();
//类型
String type = format.toString();
String strScan = rawResult.getText();
String content = new String(strScan.trim());
if (!TextUtils.isEmpty(content)) {
mListener.onDecodeSuccess(content);
}
} catch (ReaderException re) {
// continue
mListener.onDecodeFailed(-1);
} finally {
multiFormatReader.reset();
}
}
}
}
DecodeListener.java
package com.baidu.idl.face.main.decode;
public interface DecodeListener {
public void onDecodeSuccess(final String content);
public void onDecodeFailed(final int error);
}