网络上关于zxing的扫描解码这块儿的东西大多都是 基于zxing自带项目修改过来的, 而且项目里面代码太多且繁杂。
索性自己基于zxing开发了个demo代码量瞬间就少了下来, 如果要基于横屏,自己修改下代码应该会很快
项目源码
http://download.csdn.net/detail/nie312122330/8136373
自定义扫描区域如图
1.ZxingBarCodeActivity扫描界面
package com.xiaoqiang.zxing;
import java.util.concurrent.LinkedBlockingQueue;
import java.util.concurrent.ThreadPoolExecutor;
import java.util.concurrent.TimeUnit;
import android.app.Activity;
import android.content.Intent;
import android.graphics.Rect;
import android.hardware.Camera;
import android.hardware.Camera.AutoFocusCallback;
import android.hardware.Camera.PreviewCallback;
import android.hardware.Camera.Size;
import android.os.Bundle;
import android.os.Handler;
import android.os.Message;
import android.view.SurfaceHolder;
import android.view.SurfaceView;
public class ZxingBarCodeActivity extends Activity implements SurfaceHolder.Callback {
public static final String TAG = "ZbarFinderActivity";
public static final String ResultType = "ResultType";
public static final String ResultContent = "ResultContent";
private Camera mCamera;
private SurfaceHolder mHolder;
protected SurfaceView surface_view;
protected FinderView finder_view;
private Handler autoFocusHandler;
private ThreadPoolExecutor fixPool;
private LinkedBlockingQueue<Runnable> workQueue = new LinkedBlockingQueue<Runnable>();
private boolean reciveReuslt = false;
@Override
protected void onCreate(Bundle savedInstanceState) {
super.onCreate(savedInstanceState);
setContentView(R.layout.ac_zbar_finder);
//打开返回
init();
}
@SuppressWarnings("deprecation")
private void init() {
surface_view = (SurfaceView) findViewById(R.id.surface_view);
finder_view = (FinderView) findViewById(R.id.finder_view);
//扫描
mHolder = surface_view.getHolder();
//在2.3的系统中需要
mHolder.setType(SurfaceHolder.SURFACE_TYPE_PUSH_BUFFERS);
mHolder.addCallback(this);
autoFocusHandler = new Handler();
}
@Override
public void surfaceChanged(SurfaceHolder holder, int format, int width, int height) {
if (mHolder.getSurface() == null) {
return;
}
try {
mCamera.stopPreview();
} catch (Exception e) {
}
try {
mCamera.setDisplayOrientation(90);
mCamera.setPreviewDisplay(mHolder);
mCamera.setPreviewCallback(previewCallback);
mCamera.startPreview();
mCamera.autoFocus(autoFocusCallback);
} catch (Exception e) {
}
}
public boolean isReciveReuslt() {
return reciveReuslt;
}
public void setReciveReuslt(boolean reciveReuslt) {
this.reciveReuslt = reciveReuslt;
}
/**
* 结果
*/
private QrActivityHandler handler = new QrActivityHandler(this) {
@Override
public void handleMessage(Message msg) {
if (activiceReference.get() != null) {
if (msg.what == 0) {
if (!fixPool.isShutdown()) {
fixPool.shutdownNow();
}
Intent intent = new Intent(MainActivity.ACTION_SAO_RESULT);
intent.putExtras(msg.getData());
startActivity(intent);
finish();
}
}
}
};
/**
* 预览数据
*/
private PreviewCallback previewCallback = new PreviewCallback() {
public void onPreviewFrame(byte[] data, Camera camera) {
if (!reciveReuslt && !fixPool.isShutdown() && fixPool.getActiveCount() < 5) {
Camera.Parameters parameters = camera.getParameters();
Size size = parameters.getPreviewSize();
//获取预览图的大小
Rect preRect = finder_view.getScanImageRect(size);
DecodeData decodeData = new DecodeData(data, size, preRect);
Runnable command = new DecodeRunable(handler, decodeData);
fixPool.execute(command);
}
}
};
private static class QrActivityHandler extends WeakHandler<ZxingBarCodeActivity> {
public QrActivityHandler(ZxingBarCodeActivity qrFinderActivity) {
super(qrFinderActivity);
}
}
/**
* 自动对焦回调
*/
AutoFocusCallback autoFocusCallback = new AutoFocusCallback() {
public void onAutoFocus(boolean success, Camera camera) {
autoFocusHandler.postDelayed(doAutoFocus, 1000);
}
};
//自动对焦
private Runnable doAutoFocus = new Runnable() {
public void run() {
if (null == mCamera || null == autoFocusCallback) {
return;
}
mCamera.autoFocus(autoFocusCallback);
}
};
@Override
public void surfaceCreated(SurfaceHolder holder) {
try {
mCamera = Camera.open();
fixPool = new ThreadPoolExecutor(5, 5, 0L, TimeUnit.MILLISECONDS, workQueue);
} catch (Exception e) {
mCamera = null;
}
}
@Override
public void surfaceDestroyed(SurfaceHolder holder) {
if (mCamera != null) {
mCamera.setPreviewCallback(null);
mCamera.release();
mCamera = null;
}
if (null != fixPool && !fixPool.isShutdown()) {
fixPool.shutdownNow();
}
}
}
package com.xiaoqiang.zxing;
import java.util.ArrayList;
import java.util.Hashtable;
import java.util.List;
import android.graphics.Bitmap;
import android.graphics.Bitmap.Config;
import android.graphics.Matrix;
import android.graphics.Rect;
import android.hardware.Camera.Size;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.PlanarYUVLuminanceSource;
import com.google.zxing.RGBLuminanceSource;
import com.google.zxing.Result;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
public class ZxingTools {
private static Hashtable<DecodeHintType, Object> decodeConfig = new Hashtable<DecodeHintType, Object>();
static {
List<BarcodeFormat> allFormats = new ArrayList<BarcodeFormat>();
allFormats.add(BarcodeFormat.CODABAR);
allFormats.add(BarcodeFormat.CODE_39);
allFormats.add(BarcodeFormat.CODE_93);
allFormats.add(BarcodeFormat.CODE_128);
allFormats.add(BarcodeFormat.DATA_MATRIX);
allFormats.add(BarcodeFormat.EAN_8);
allFormats.add(BarcodeFormat.EAN_13);
allFormats.add(BarcodeFormat.ITF);
allFormats.add(BarcodeFormat.QR_CODE);
allFormats.add(BarcodeFormat.RSS_14);
allFormats.add(BarcodeFormat.EAN_13);
allFormats.add(BarcodeFormat.RSS_EXPANDED);
allFormats.add(BarcodeFormat.UPC_A);
allFormats.add(BarcodeFormat.UPC_E);
decodeConfig.put(DecodeHintType.POSSIBLE_FORMATS, allFormats);
}
/**
* 解析DecodeData
* @param decodeData
* @param needResultBitmap
* @return
*/
public static ZxingResult decodeBinayBitmap(DecodeData decodeData, boolean needResultBitmap) {
Bitmap barCodeBitMap = getBarCodeBitMapByRoate90(decodeData);
Rect previewRect = new Rect(0, 0, barCodeBitMap.getWidth(), barCodeBitMap.getHeight());
return decodeBitmap(barCodeBitMap, previewRect, needResultBitmap);
}
/**
* 解析PlanarYUVData
* @param data
* @param width
* @param height
* @param previewRect
* @param needResultBitmap
* @return
*/
public static ZxingResult decodePlanarYUVData(byte[] data, int width, int height, Rect previewRect, boolean needResultBitmap) {
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, width, height, previewRect.left, previewRect.top, previewRect.width(), previewRect.height(), false);
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result = decodeBinaryBitmap(binaryBitmap);
if (null != result) {
Bitmap resultBitmap = null;
if (needResultBitmap) {
resultBitmap = getBarCodeBitMap(source);
}
return new ZxingResult(result, resultBitmap);
}
return null;
}
/**
* 解析Bitmap
* @param bitmap
* @param previewRect
* @param needResultBitmap
* @return
*/
public static ZxingResult decodeBitmap(Bitmap bitmap, Rect previewRect, boolean needResultBitmap) {
int[] pixels = new int[bitmap.getWidth() * bitmap.getHeight()];
bitmap.getPixels(pixels, 0, bitmap.getWidth(), previewRect.left, previewRect.top, previewRect.right, previewRect.bottom);
RGBLuminanceSource source = new RGBLuminanceSource(bitmap.getWidth(), bitmap.getHeight(), pixels);
BinaryBitmap binaryBitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result = decodeBinaryBitmap(binaryBitmap);
if (null != result) {
Bitmap resultBitmap = null;
if (needResultBitmap) {
resultBitmap = Bitmap.createBitmap(previewRect.width(), previewRect.height(), Config.ARGB_4444);
resultBitmap.setPixels(pixels, 0, previewRect.width(), 0, 0, previewRect.width(), previewRect.height());
}
return new ZxingResult(result, resultBitmap);
}
return null;
}
/**
* 解析BinaryBitmap
* @param binaryBitmap
* @return
*/
public static Result decodeBinaryBitmap(BinaryBitmap binaryBitmap) {
MultiFormatReader multiFormatReader = new MultiFormatReader();
multiFormatReader.setHints(decodeConfig);
Result decode = null;
try {
decode = multiFormatReader.decode(binaryBitmap);
} catch (NotFoundException e) {
} finally {
multiFormatReader.reset();
}
return decode;
}
/**
* 生成二维码
* @param content
* @param needWidth
* @param needHeight
* @return
* @throws Exception
*/
public static Bitmap encodeQr(String content, int needWidth, int needHeight) throws Exception {
Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
MultiFormatWriter writer = new MultiFormatWriter();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.QR_CODE, needWidth, needHeight);
return convertBitMatrix2BitMap(bitMatrix);
}
/**
* 生成一维码(128)
* @param content
* @param needWidth
* @param needHeight
* @return
* @throws Exception
*/
public static Bitmap encodeBarcode(String content, int needWidth, int needHeight) throws Exception {
Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
MultiFormatWriter writer = new MultiFormatWriter();
BitMatrix bitMatrix = writer.encode(content, BarcodeFormat.CODE_128, needWidth, needHeight);
return convertBitMatrix2BitMap(bitMatrix);
}
/**
* 将BitMatrix转化为Bitmap
* @param bitMatrix
* @return
*/
public static Bitmap convertBitMatrix2BitMap(BitMatrix bitMatrix) {
int bitmapWidth = bitMatrix.getWidth();
int bitmapHeight = bitMatrix.getHeight();
int[] pixels = new int[bitmapWidth * bitmapHeight];
// x The horizontal component (i.e. which column)
// y The vertical component (i.e. which row)
for (int x = 0; x < bitmapWidth; x++) {
for (int y = 0; y < bitmapHeight; y++) {
if (bitMatrix.get(x, y)) {
pixels[y * bitmapWidth + x] = 0xff000000; // black pixel
} else {
pixels[y * bitmapWidth + x] = 0xffffffff; // white pixel
}
}
}
Bitmap createBitmap = Bitmap.createBitmap(bitmapWidth, bitmapHeight, Bitmap.Config.ARGB_4444);
createBitmap.setPixels(pixels, 0, bitmapWidth, 0, 0, bitmapWidth, bitmapHeight);
return createBitmap;
}
/**
* 从PlanarYUVLuminanceSource获取Bitmap
* @param source
* @return
*/
public static Bitmap getBarCodeBitMap(PlanarYUVLuminanceSource source) {
int[] pixels = source.renderThumbnail();
int width = source.getThumbnailWidth();
int height = source.getThumbnailHeight();
return Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_4444);
}
/**
* 根据DecodeData获取Bitmap
* @param decodeData
* @return
*/
public static Bitmap getBarCodeBitMap(DecodeData decodeData) {
byte[] data = decodeData.getData();
Size size = decodeData.getSourceSize();
Rect preRect = decodeData.getPreRect();
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, size.width, size.height, preRect.left, preRect.top, preRect.width(), preRect.height(), false);
int[] pixels = source.renderThumbnail();
int width = source.getThumbnailWidth();
int height = source.getThumbnailHeight();
return Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_4444);
}
/**
* 根据DecodeData获取旋转90度后的bitmap
* @param decodeData
* @return
*/
public static Bitmap getBarCodeBitMapByRoate90(DecodeData decodeData) {
byte[] data = decodeData.getData();
Size sourceSize = decodeData.getSourceSize();
Rect preRect = decodeData.getPreRect();
PlanarYUVLuminanceSource source = new PlanarYUVLuminanceSource(data, sourceSize.width, sourceSize.height, preRect.left, preRect.top, preRect.width(), preRect.height(), false);
int[] pixels = source.renderThumbnail();
int width = source.getThumbnailWidth();
int height = source.getThumbnailHeight();
Bitmap sourceBitmap = Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.ARGB_4444);
Matrix matrix = new Matrix();
matrix.reset();
matrix.setRotate(90);
Bitmap resultBitmap = Bitmap.createBitmap(sourceBitmap, 0, 0, sourceBitmap.getWidth(), sourceBitmap.getHeight(), matrix, true);
if (!sourceBitmap.isRecycled())
sourceBitmap.recycle();
return resultBitmap;
}
/**
* 旋转YUVdata--旋转后size重设
* @param data
* @param size
* @return
*/
public static byte[] roate90YUVdata(byte[] data, Size size) {
byte[] rotatedData = new byte[data.length];
for (int y = 0; y < size.height; y++) {
for (int x = 0; x < size.width; x++)
rotatedData[x * size.height + size.height - y - 1] = data[x + y * size.width];
}
int tmp = size.width;
size.width = size.height;
size.height = tmp;
return rotatedData;
}
}
原文:http://blog.csdn.net/nie312122330/article/details/40923723