Zxing二维码扫描

网络上关于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();
		}
	}

}

2、抽取的工具类

ZxingTools

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;
	}

}

项目源码

时间: 2024-12-28 01:02:35

Zxing二维码扫描的相关文章

Android—ZXing二维码扫描遇到的问题

最近工作中需要开发带有二维码扫描功能的软件(基于开源项目ZXing),遇到的问题记录一下,也希望给大家带来帮助. 1.首先因为扫描要开摄像机所以加权限是一定的,不然后面什么都不能进行 <uses-permission android:name="android.permission.CAMERA" /> 2.设置扫描框的大小: 在com.zxing.camera包中查找 private static final int MIN_FRAME_WIDTH = 240;  pri

自定义ZXing二维码扫描界面并解决取景框拉伸等问题

先看效果 扫描内容是下面这张,二维码是用zxing库生成的 由于改了好几个类,还是去年的事都忘得差不多了,所以只能上这个类的代码了,主要就是改了这个CaptureActivity.java 1 package com.zxing.activity; 2 3 import java.io.IOException; 4 import java.util.Vector; 5 6 import android.app.Activity; 7 import android.content.Intent;

二维码扫描开源库ZXing定制化

(抱歉文章还在修改但是不小心发布了= =) 最近在用ZXing这个开源库做二维码的扫描模块,开发过程的一些代码修改和裁剪的经验和大家分享一下. 我的代码库: https://github.com/SickWorm/ZXingDialog 代码没有在github维护,所以没有log.但是所有修改的地方我都加上了“@ch”的注释,以方便定位 官方源码: https://github.com/zxing/zxing 实现功能: 1.功能裁剪(只保留QRCode二维码扫描功能,去掉条形码等其他码扫描功能

【IOS】集成zxing(二维码扫描)

现在zxing已经到了2.2版本,以前的集成方式出了点问题.下面我做出一点修正.以前的版本的集成方法,参考:http://blog.devtang.com/blog/2012/12/23/use-zxing-library/按照以前的方式做好后  然后就是适配以下现在的版本的修改1.增加   SenTestingKit  框架 设置为Optional2.把目录 iphone/ZXingWidget 下的Tests删了3.保留目录 cpp/core/src 的bigint文件最后提醒:  设置查找

Google zxing实现二维码扫描完美解决方案

最近因项目需求,需要在App中集成二维码扫描的功能.网上找了很多资料,最后决定使用Google的zxing来实现.实现的过程遇到了很多的坑,也是因为这些坑在网上没有具体的解决方案,今天就把我的实现过程分享给大家. 我会分为两步来和大家分享: (1)项目中如何集成zxing (2)如何修改取景框的样式 (3)总结填坑 1.项目中集成zxing 在项目中集成zxing,网上有很多的教程也说的比较详细了,zxing中的内容很多,涵盖了很多的扫码功能(不仅仅局限于扫描二维码...).步骤很简单,只需要我

【转】Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果--不错

原文网址:http://blog.csdn.net/xiaanming/article/details/10163203 转载请注明出处:http://blog.csdn.net/xiaanming/article/details/10163203 了解二维码这个东西还是从微信中,当时微信推出二维码扫描功能,自己感觉挺新颖的,从一张图片中扫一下竟然能直接加好友,不可思议啊,那时候还不了解二维码,呵呵,然后做项目的时候,老板说要加上二维码扫描功能,然后自己的屁颠屁颠的去百度,google啥的,发现

条码扫描二维码扫描—ZXing android 改进版本

看了Vurtexゞ. 文章<[Android实例] 条码扫描二维码扫描——ZXing android 源码简化 (附:支持中文) >的基础上对代码进行了修改 1.增加了将代码嵌套入自己工程后传值的办法(初学,如果有更好的方法也希望告诉我,先谢谢了) 2.扫码界面进行了处理(初步实现了现有某些软件的样子,至于长的像谁就不说了) //画四个角的代码<br>paint.setColor(frameColor); canvas.drawRect(15 + frame.left, 15 +

Android 基于google Zxing实现二维码、条形码扫描,仿微信二维码扫描效果

了解二维码这个东西还是从微信中,当时微信推出二维码扫描功能.自己感觉挺新颖的,从一张图片中扫一下居然能直接加好友,不可思议啊,那时候还不了解二维码.呵呵,然后做项目的时候.老板说要加上二维码扫描功能.然后自己的屁颠屁颠的去百度,google啥的.发现非常多朋友都有介绍二维码扫描的功能,然后我就跟着人家的介绍自己搞起了二维码扫描功能,跟着人家的帖子,非常快我的项目就增加了扫描二维码的功能,然后自己还非常开心. 随着微信的到来,二维码越来越火爆,随处能看到二维码,比方商城里面,肯德基,餐厅等等.对于

Zxing图片拉伸解决 Android 二维码扫描

二维码扫描  Android Zxing图片拉伸解决 Zxing是google提供的二维码扫描工程 默认是横屏的  转换成竖屏后图片出现拉伸 这里提供解决办法: Zxing  修改 CameraConfigurationManager.java文件的 void initFromCameraParameters(Camera camera)方法 在 Log.d(TAG, "Screen resolution: " + screenResolution);这句之后增加 Point scre