Android ZXing 二维码、条形码扫描介绍

本帖最后由 Shims 于 2013-11-9 12:39 编辑

最近公司的Android项目需要用到摄像头做条码或二维码的扫描,Google一下,发现一个开源的 ZXing项目。它提供二维码和条形码的扫描。扫描条形码就是直接读取条形码的内容,扫描二维码是按照自己指定的二维码格式进行编码和解码。

1.什么是二维码和条形码?

                        

二维条形码最早发明于日本,它是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的,在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理。它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化等特点。

条形码(barcode)是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符。常见的条形码是由反射率相差很大的黑条(简称条)和白条(简称空)排成的平行线图案。条形码可以标出物品的生产国、制造厂家、商品名称、生产日期、图书分类号、邮件起止地点、类别、日期等许多信息,因而在商品流通、图书管理、邮政管理、银行系统等许多领域都得到广泛的应用。

2.ZXing基本介绍

ZXing是一个开源Java类库用于解析多种格式的条形码和二维码.官网:http://code.google.com/p/zxing/

截止目前为止最新版本提供以下编码格式的支持:

  • UPC-A and UPC-E
  • EAN-8 and EAN-13
  • Code 39
  • Code 93
  • Code 128
  • QR Code
  • ITF
  • Codabar
  • RSS-14 (all variants)
  • Data Matrix
  • PDF 417 (‘alpha‘ quality)
  • Aztec (‘alpha‘ quality)

同时官网提供了 Android、cpp、C#、iPhone、j2me、j2se、jruby、objc、rim、symbian等多种应用的类库,具体详情可以参考下载的源码包中。

3.Android端编码演示

这里使用的ZXing是经过简化版的,去除了一些一般使用不必要的文件,项目工程和效果截图如下:

    

其中encoding包是在原基础上加上去的,功能是根据传入的字符串来生成二维码图片,返回一个Bitmap,其余的包是ZXing项目自带的。另外对扫描界面的布局也进行了修改,官方的扫描界面是横向的,我改成了纵向的,并加入了顶部的Tab和取消按钮(camera.xml),另外还需要的一些文件是colors.xml、ids.xml,这些都是原本ZXing项目中自带的,最后就是libs下面的jar包。

接下来看如何使用,首先是把ZXing项目中的一些文件拷贝到我们自己的项目中,然后在Mainifest文件中进行配置权限:

  1. <font color="#000"><font face="Arial">    <uses-permission android:name="android.permission.VIBRATE" />
  2. <uses-permission android:name="android.permission.CAMERA" />
  3. <uses-feature android:name="android.hardware.camera" />
  4. <uses-feature android:name="android.hardware.camera.autofocus" /></font></font>

复制代码

还有就是扫描界面Activity的配置:

  1. <font color="#000">   <activity
  2. android:configChanges="orientation|keyboardHidden"
  3. android:name="com.zxing.activity.CaptureActivity"
  4. android:screenOrientation="portrait"
  5. android:theme="@android:style/Theme.NoTitleBar.Fullscreen"
  6. android:windowSoftInputMode="stateAlwaysHidden" >
  7. </activity></font>

复制代码

接下来是我自己项目的布局文件:

  1. <font color="#000"><font face="Arial"><?xml version="1.0" encoding="utf-8"?>
  2. <LinearLayout xmlns:android="http://schemas.android.com/apk/res/android"
  3. android:layout_width="fill_parent"
  4. android:layout_height="fill_parent"
  5. android:background="@android:color/white"
  6. android:orientation="vertical" >
  7. <Button
  8. android:id="@+id/btn_scan_barcode"
  9. android:layout_width="fill_parent"
  10. android:layout_height="wrap_content"
  11. android:layout_marginTop="30dp"
  12. android:text="Open camera" />
  13. <LinearLayout
  14. android:orientation="horizontal"
  15. android:layout_marginTop="10dp"
  16. android:layout_width="fill_parent"
  17. android:layout_height="wrap_content">
  18. <TextView
  19. android:layout_width="wrap_content"
  20. android:layout_height="wrap_content"
  21. android:textColor="@android:color/black"
  22. android:textSize="18sp"
  23. android:text="Scan result:" />
  24. <TextView
  25. android:id="@+id/tv_scan_result"
  26. android:layout_width="fill_parent"
  27. android:textSize="18sp"
  28. android:textColor="@android:color/black"
  29. android:layout_height="wrap_content" />
  30. </LinearLayout>
  31. <EditText
  32. android:id="@+id/et_qr_string"
  33. android:layout_width="fill_parent"
  34. android:layout_height="wrap_content"
  35. android:layout_marginTop="30dp"
  36. android:hint="Input the text"/>
  37. <Button
  38. android:id="@+id/btn_add_qrcode"
  39. android:layout_width="fill_parent"
  40. android:layout_height="wrap_content"
  41. android:text="Generate QRcode" />
  42. <ImageView
  43. android:id="@+id/iv_qr_image"
  44. android:layout_width="wrap_content"
  45. android:layout_height="wrap_content"
  46. android:layout_marginTop="10dp"
  47. android:layout_gravity="center"/>
  48. </LinearLayout></font></font>

复制代码

下面是主Activity的代码,主要功能是打开扫描框、显示扫描结果、根据输入的字符串生成二维码图片:

  1. <font color="#000"><font face="Arial">public class BarCodeTestActivity extends Activity {
  2. /** Called when the activity is first created. */
  3. private TextView resultTextView;
  4. private EditText qrStrEditText;
  5. private ImageView qrImgImageView;
  6. @Override
  7. public void onCreate(Bundle savedInstanceState) {
  8. super.onCreate(savedInstanceState);
  9. setContentView(R.layout.main);
  10. resultTextView = (TextView) this.findViewById(R.id.tv_scan_result);
  11. qrStrEditText = (EditText) this.findViewById(R.id.et_qr_string);
  12. qrImgImageView = (ImageView) this.findViewById(R.id.iv_qr_image);
  13. Button scanBarCodeButton = (Button) this.findViewById(R.id.btn_scan_barcode);
  14. scanBarCodeButton.setOnClickListener(new OnClickListener() {
  15. @Override
  16. public void onClick(View v) {
  17. //打开扫描界面扫描条形码或二维码
  18. Intent openCameraIntent = new Intent(BarCodeTestActivity.this,CaptureActivity.class);
  19. startActivityForResult(openCameraIntent, 0);
  20. }
  21. });
  22. Button generateQRCodeButton = (Button) this.findViewById(R.id.btn_add_qrcode);
  23. generateQRCodeButton.setOnClickListener(new OnClickListener() {
  24. @Override
  25. public void onClick(View v) {
  26. try {
  27. String contentString = qrStrEditText.getText().toString();
  28. if (!contentString.equals("")) {
  29. //根据字符串生成二维码图片并显示在界面上,第二个参数为图片的大小(350*350)
  30. Bitmap qrCodeBitmap = EncodingHandler.createQRCode(contentString, 350);
  31. qrImgImageView.setImageBitmap(qrCodeBitmap);
  32. }else {
  33. Toast.makeText(BarCodeTestActivity.this, "Text can not be empty", Toast.LENGTH_SHORT).show();
  34. }
  35. } catch (WriterException e) {
  36. // TODO Auto-generated catch block
  37. e.printStackTrace();
  38. }
  39. }
  40. });
  41. }
  42. @Override
  43. protected void onActivityResult(int requestCode, int resultCode, Intent data) {
  44. super.onActivityResult(requestCode, resultCode, data);
  45. //处理扫描结果(在界面上显示)
  46. if (resultCode == RESULT_OK) {
  47. Bundle bundle = data.getExtras();
  48. String scanResult = bundle.getString("result");
  49. resultTextView.setText(scanResult);
  50. }
  51. }
  52. }</font></font>

复制代码

其中生成二维码图片的代码在EncodingHandler.java中:

  1. <font color="#000"><font face="Arial">public final class EncodingHandler {
  2. private static final int BLACK = 0xff000000;
  3. public static Bitmap createQRCode(String str,int widthAndHeight) throws WriterException {
  4. Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
  5. hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
  6. BitMatrix matrix = new MultiFormatWriter().encode(str,
  7. BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
  8. int width = matrix.getWidth();
  9. int height = matrix.getHeight();
  10. int[] pixels = new int[width * height];
  11. for (int y = 0; y < height; y++) {
  12. for (int x = 0; x < width; x++) {
  13. if (matrix.get(x, y)) {
  14. pixels[y * width + x] = BLACK;
  15. }
  16. }
  17. }
  18. Bitmap bitmap = Bitmap.createBitmap(width, height,
  19. Bitmap.Config.ARGB_8888);
  20. bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
  21. return bitmap;
  22. }
  23. }</font></font>

复制代码

最后是在哪里对扫描结果进行解码,进入CaptureActivity.java找到下面这个方法便可以对自己对结果进行操作:

  1. <font color="#000"><font face="Arial">  /**
  2. * Handler scan result
  3. * @param result
  4. * @param barcode
  5. */
  6. public void handleDecode(Result result, Bitmap barcode) {
  7. inactivityTimer.onActivity();
  8. playBeepSoundAndVibrate();
  9. String resultString = result.getText();
  10. //FIXME
  11. if (resultString.equals("")) {
  12. Toast.makeText(CaptureActivity.this, "Scan failed!", Toast.LENGTH_SHORT).show();
  13. }else {
  14. //                        System.out.println("Result:"+resultString);
  15. Intent resultIntent = new Intent();
  16. Bundle bundle = new Bundle();
  17. bundle.putString("result", resultString);
  18. resultIntent.putExtras(bundle);
  19. this.setResult(RESULT_OK, resultIntent);
  20. }
  21. CaptureActivity.this.finish();
  22. }</font></font>

复制代码

4.Java端编码演示

在Java端上实现条形码(EAN-13)和二维码(QRCode) 的编码和解码的示例,以供大家参考,用到了源码中core和javase下面的相关源代码,附件提供自己编译之后的lib包:

zxing.jar
zxing-j2se.jar

有关各种手机系统的应用,有兴趣的朋友可以下载官方源码包,包下有具体详细的应用介绍。

1)二维码(QRCode)的编码和解码演示:

编码示例:

  1. package michael.zxing;
  2. import java.io.File;
  3. import java.util.Hashtable;
  4. import com.google.zxing.BarcodeFormat;
  5. import com.google.zxing.EncodeHintType;
  6. import com.google.zxing.MultiFormatWriter;
  7. import com.google.zxing.client.j2se.MatrixToImageWriter;
  8. import com.google.zxing.common.BitMatrix;
  9. import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
  10. /**
  11. * [url=home.php?mod=space&uid=618199]@blog[/url] http://sjsky.iteye.com
  12. * @author Michael
  13. */
  14. public class ZxingEncoderHandler {
  15. /**
  16. * 编码
  17. * @param contents
  18. * @param width
  19. * @param height
  20. * @param imgPath
  21. */
  22. public void encode(String contents, int width, int height, String imgPath) {
  23. Hashtable<Object, Object> hints = new Hashtable<Object, Object>();
  24. // 指定纠错等级
  25. hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
  26. // 指定编码格式
  27. hints.put(EncodeHintType.CHARACTER_SET, "GBK");
  28. try {
  29. BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,
  30. BarcodeFormat.QR_CODE, width, height, hints);
  31. MatrixToImageWriter
  32. .writeToFile(bitMatrix, "png", new File(imgPath));
  33. } catch (Exception e) {
  34. e.printStackTrace();
  35. }
  36. }
  37. /**
  38. * @param args
  39. */
  40. public static void main(String[] args) {
  41. String imgPath = "d:/1.png";
  42. String contents = "Hello Word!";
  43. int width = 300, height = 300;
  44. ZxingEncoderHandler handler = new ZxingEncoderHandler();
  45. handler.encode(contents, width, height, imgPath);
  46. }
  47. }

复制代码

运行后生成的二维码图片如下:

用手机的二维码扫描软件(本人用的:android 快拍二维码 )来测试下,识别成功的截图如下:

解码示例:

  1. package michael.zxing;
  2. import java.awt.image.BufferedImage;
  3. import java.io.File;
  4. import java.util.Hashtable;
  5. import javax.imageio.ImageIO;
  6. import com.google.zxing.BinaryBitmap;
  7. import com.google.zxing.DecodeHintType;
  8. import com.google.zxing.LuminanceSource;
  9. import com.google.zxing.MultiFormatReader;
  10. import com.google.zxing.Result;
  11. import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
  12. import com.google.zxing.common.HybridBinarizer;
  13. /**
  14. * @blog http://sjsky.iteye.com
  15. * @author Michael
  16. */
  17. public class ZxingDecoderHandler {
  18. /**
  19. * @param imgPath
  20. * [url=home.php?mod=space&uid=7300]@return[/url] String
  21. */
  22. public String decode(String imgPath) {
  23. BufferedImage image = null;
  24. Result result = null;
  25. try {
  26. image = ImageIO.read(new File(imgPath));
  27. if (image == null) {
  28. System.out.println("the decode image may be not exit.");
  29. }
  30. LuminanceSource source = new BufferedImageLuminanceSource(image);
  31. BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
  32. Hashtable<Object, Object> hints = new Hashtable<Object, Object>();
  33. hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
  34. result = new MultiFormatReader().decode(bitmap, hints);
  35. return result.getText();
  36. } catch (Exception e) {
  37. e.printStackTrace();
  38. }
  39. return null;
  40. }
  41. /**
  42. * @param args
  43. */
  44. public static void main(String[] args) {
  45. String imgPath = "d:/1.png";
  46. ZxingDecoderHandler handler = new ZxingDecoderHandler();
  47. String decodeContent = handler.decode(imgPath);
  48. System.out.println("解码内容如下:");
  49. System.out.println(decodeContent);
  50. }
  51. }

复制代码

Hello Word!

2)条形码(EAN-13)的编码和解码演示:

编码示例:

  1. package michael.zxing;
  2. import java.io.File;
  3. import com.google.zxing.BarcodeFormat;
  4. import com.google.zxing.MultiFormatWriter;
  5. import com.google.zxing.client.j2se.MatrixToImageWriter;
  6. import com.google.zxing.common.BitMatrix;
  7. /**
  8. * @blog http://sjsky.iteye.com
  9. * @author Michael
  10. */
  11. public class ZxingEAN13EncoderHandler {
  12. /**
  13. * 编码
  14. * @param contents
  15. * @param width
  16. * @param height
  17. * @param imgPath
  18. */
  19. public void encode(String contents, int width, int height, String imgPath) {
  20. int codeWidth = 3 + // start guard
  21. (7 * 6) + // left bars
  22. 5 + // middle guard
  23. (7 * 6) + // right bars
  24. 3; // end guard
  25. codeWidth = Math.max(codeWidth, width);
  26. try {
  27. BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,
  28. BarcodeFormat.EAN_13, codeWidth, height, null);
  29. MatrixToImageWriter
  30. .writeToFile(bitMatrix, "png", new File(imgPath));
  31. } catch (Exception e) {
  32. e.printStackTrace();
  33. }
  34. }
  35. /**
  36. * @param args
  37. */
  38. public static void main(String[] args) {
  39. String imgPath = "d:/2.png";
  40. // 益达无糖口香糖的条形码
  41. String contents = "6923450657713";
  42. int width = 105, height = 50;
  43. ZxingEAN13EncoderHandler handler = new ZxingEAN13EncoderHandler();
  44. handler.encode(contents, width, height, imgPath);
  45. }
  46. }

复制代码

运行后生成条形码图片如下:

用手机的条形码扫描软件(本人用的:android 快拍二维码 )来测试下,识别成功的截图如下:

解码示例:

  1. package michael.zxing;
  2. import java.awt.image.BufferedImage;
  3. import java.io.File;
  4. import javax.imageio.ImageIO;
  5. import com.google.zxing.BinaryBitmap;
  6. import com.google.zxing.LuminanceSource;
  7. import com.google.zxing.MultiFormatReader;
  8. import com.google.zxing.Result;
  9. import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
  10. import com.google.zxing.common.HybridBinarizer;
  11. /**
  12. * @blog http://sjsky.iteye.com
  13. * @author Michael
  14. */
  15. public class ZxingEAN13DecoderHandler {
  16. /**
  17. * @param imgPath
  18. * @return String
  19. */
  20. public String decode(String imgPath) {
  21. BufferedImage image = null;
  22. Result result = null;
  23. try {
  24. image = ImageIO.read(new File(imgPath));
  25. if (image == null) {
  26. System.out.println("the decode image may be not exit.");
  27. }
  28. LuminanceSource source = new BufferedImageLuminanceSource(image);
  29. BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
  30. result = new MultiFormatReader().decode(bitmap, null);
  31. return result.getText();
  32. } catch (Exception e) {
  33. e.printStackTrace();
  34. }
  35. return null;
  36. }
  37. /**
  38. * @param args
  39. */
  40. public static void main(String[] args) {
  41. String imgPath = "d:/2.png";
  42. ZxingEAN13DecoderHandler handler = new ZxingEAN13DecoderHandler();
  43. String decodeContent = handler.decode(imgPath);
  44. System.out.println("解码内容如下:");
  45. System.out.println(decodeContent);
  46. }
  47. }

复制代码

解码内容如下:

6923450657713

时间: 2024-07-30 03:42:27

Android ZXing 二维码、条形码扫描介绍的相关文章

Android基于Google Zxing实现二维码/条形码扫描、生成二维码/条形码

 二维码/条形码生成器 二维码/条形码扫描器 一.二维码与条形码工作原理 目前的很多应用上都有扫码功能,当时微信推出二维码扫码功能时,觉得imagine,通过一张简单的图片就能扫描添加还有,还有分享名片功能(也是一张二维码图片,识别扫描). 下面小编将通过文章主要介绍QRCode方面技术. QRCode是被广泛应用的一种二维码,解码速度快.二维码相对于条形码来说,二维码的存储数据量更大,空间利用率高,有一定的容错性. 二维码原理介绍: 二维码是用某种特定的几何图形按一定的规律在平面上分布的黑

Android之二维码的扫描与生成

今天,来学习使用怎么实现二维码的扫一扫和二维码的生成. 要想实现二维码的扫一扫与二维码的生成,就得必须了解二维码的特征. QRcode: QRCode简介: QRCode全称Quick Response Code. 通过在一个矩形区域内使用黑白像素来进行编码. 高纠错性.高可用性.高识别性. ZXing简介: ZXing是一个开放源码的,用java实现的多种格式为1D/2D条码图形处理库,它包含了联系到其他语言的端口. ZXing可以实现使用手机的内置的摄像头完成条形码的扫描与解码. 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

iOS系统原生二维码条形码扫描

本文讲述如何用系统自带的东东实现二维码扫描的功能:点击当前页面的某个按钮,创建扫描VIEW.细心的小伙伴可以发现 title被改变了,返回按钮被隐藏了.这个代码自己写就行了,与本文关系不大...绿色的线会上下跑,不要担心:D 实现效果如下: 1.在工程中添加框架AVFoundation.framework 2.声明代理:AVCaptureMetadataOutputObjectsDelegate . define 几个东东用来画框.画线: #define SCANVIEW_EdgeTop 40.

Android Zxing 二维码添加闪光灯的功能

主要修改zxing中的.Zxing.camera 包下的CameraManager类 开关代码 在CamereManager中增加 //提供給其他activity調用 public void flashHandler() { //camera.startPreview(); Parameters parameters = camera.getParameters(); // 判断闪光灯当前状态來修改 if (Parameters.FLASH_MODE_OFF.equals(parameters.

【转】 Android 基于google Zxing实现对手机中的二维码进行扫描--不错

原文网址:http://blog.csdn.net/xiaanming/article/details/14450809 转载请注明出处:http://blog.csdn.net/xiaanming/article/details/14450809 我之前写了一篇关于google Zxing扫描二维码的文章,效果是仿微信的效果,有兴趣的朋友可以去看看基于google Zxing实现二维码.条形码扫描,仿微信二维码扫描效果,有时候我们有这样子的需求,需要扫描手机中有二维码的的图片,所以今天实现的就

Android 基于google Zxing实现对手机中的二维码进行扫描

转载请注明出处:http://blog.csdn.net/xiaanming/article/details/14450809 有时候我们有这样子的需求,需要扫描手机中有二维码的的图片,所以今天实现的就是对手机中的二维码图片进行扫描,我这里是直接在原来的工程上面加的这个功能,下面就简单介绍下这个小功能的实现,首先我在界面上加了一个ImageButton,图片还是用的微信的图片,下面是扫描界面的title <?xml version="1.0" encoding="utf

Android项目实战(四十四):Zxing二维码切换横屏扫描

原文:Android项目实战(四十四):Zxing二维码切换横屏扫描 Demo链接 默认是竖屏扫描,但是当我们在清单文件中配置横屏显示的时候: <activity android:name=".CaptureActivity" android:screenOrientation="landscape" android:theme="@android:style/Theme.NoTitleBar.Fullscreen" /> 这时候扫描

Android之zxing二维码生成与识别

二维码: 是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的: 在代码编制上巧妙的利用构成计算机内部逻辑基础的0和1比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图像输入设备或光电扫描设备自动识读以实现信息自动处理: 二维码能够在横向和纵向两个方位同时表达信息,因此能在很小的面积内表达大量的信息: 二维码相对于条形码的优势就是省空间:   zxing简介: zxing是一个开放源码的,用java实现的多种格式的1D/2D条码图像处