二维码QRCode

QRCode 二维码

1 、简介
二维条形码最早发明于日本,它是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息
的,在代码编制上巧妙地利用构成计算机内部逻辑基础的“0 ”、“1 ”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字
数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理。它具有条码技术的一些共性:每种码制有其特定的字符集;
每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化等特点。
条形码(bar code)是将宽度不等的多个黑条和空白,按照一定的编码规则排列,用以表达一组信息的图形标识符。常见的条形码是由反
射率相差很大的黑条(简称条)和白条(简称空)排成的平行线图案。条形码可以标出物品的生产国、制造厂家、商品名称、生产日期、
图书分类号、邮件起止地点、类别、日期等许多信息,因而在商品流通、图书管理、邮政管理、银行系统等许多领域都得到广泛的应用。
2 、ZX ing基本介绍
ZX ing是一个开源Jav a类库用于解析多种格式的条形码和二维码. 官
网:ht t p: //code. google. com /p/zx ing/(ht t ps : //git hub. com /zx ing/zx ing)
截止目前为止最新版本提供以下编码格式的支持:
U PC -A  and U PC - E
EAN -8   and  EAN -1 3
C ode  3 9
C ode  9 3
C ode  1 2 8
Q R   C ode
I T F
C odabar
R S S -1 4   (all  v ar iant s )
Dat a Mat r ix
PDF   4 1 7   ('alpha'  qualit y )
Azt ec   ('alpha'  qualit y )
同时G it Hub提供了  Andr oid、cpp、C #、iPhone、j2 m e、j2 s e、jr uby 、objc、r im 、s y m bian等多种应用的类库,具体详情可以参
考下载的源码包中。
QR码符号共有40种规格,分别为版本1、版本2„„版本40。版本1的规格为21模块×21模块,版本2为25模块×25模块,以此类推,每一版本符
号比前一版本每边增加4个模块,直到版本40,规格为177模块×177模块。其中最高版本40可容纳多达1850个大写字母或2710个数字或1108
个字节,或500多个汉字,比普通条码信息容量约高几十倍。由于其高密度编码,信息容量大,所以被广泛采用。
下图1为版本2的示意图(共25模块×25模块):

二维码的结构。
3 、Andr oid端编码演示
这里使用的ZX ing是经过简化版的,去除了一些一般使用不必要的文件,项目工程和效果截图如下:
其中enc odi ng包是在原基础上加上去的,功能是根据传入的字符串来生成二维码图片,返回一个B i tmap,其余的包是Z Xi ng项目自带的。另
外对扫描界面的布局也进行了修改,官方的扫描界面是横向的,改成了纵向的,并加入了顶部的Tab和取消按钮(c amera. xml ),另外还需
要的一些文件是c ol ors. xml 、i ds. xml ,这些都是原本Z Xi ng项目中自带的,最后就是l i bs下面的j ar包。
接下来看如何使用,首先是把Z Xi ng项目中的一些文件拷贝到我们自己的项目中,然后在Mai ni fest文件中进行配置权限:
1.  <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"/>
还有就是扫描界面Ac t iv it y 的配置:
1.  <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>
接下来是我自己项目的布局文件:
1.  <?xmlversion="1.0"encoding="utf-8"?>
2.  <LinearLayoutxmlns: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.
8.      <Button
9.          android:id="@+id/btn_scan_barcode"
10.          android:layout_width="fill_parent"
11.          android:layout_height="wrap_content"
12.          android:layout_marginTop="30dp"
13.          android:text="Open camera"/>
14.     
15.      <LinearLayout
16.          android:orientation="horizontal"
17.          android:layout_marginTop="10dp"
18.          android:layout_width="fill_parent"
19.          android:layout_height="wrap_content">
20.         
21.          <TextView
22.          android:layout_width="wrap_content"
23.          android:layout_height="wrap_content"
24.          android:textColor="@android:color/black"
25.          android:textSize="18sp"
26.          android:text="Scan result:"/>
27.         
28.          <TextView
29.          android:id="@+id/tv_scan_result"
30.          android:layout_width="fill_parent"
31.          android:textSize="18sp"
32.          android:textColor="@android:color/black"
33.          android:layout_height="wrap_content"/>
34.      </LinearLayout>
35.     
36.      <EditText
37.          android:id="@+id/et_qr_string"
38.          android:layout_width="fill_parent"
39.          android:layout_height="wrap_content"
40.          android:layout_marginTop="30dp"
41.          android:hint="Input the text"/>
42.     
43.      <Button
44.          android:id="@+id/btn_add_qrcode"
45.          android:layout_width="fill_parent"
46.          android:layout_height="wrap_content"
47.          android:text="Generate QRcode"/>
48.     
49.      <ImageView
50.          android:id="@+id/iv_qr_image"
51.          android:layout_width="wrap_content"
52.          android:layout_height="wrap_content"
53.          android:layout_marginTop="10dp"
54.          android:layout_gravity="center"/>
55.
56.  </LinearLayout>
下面是主Ac t iv it y 的代码,主要功能是打开扫描框、显示扫描结果、根据输入的字符串生成二维码图片:
1.  publicclass BarCodeTestActivity extends Activity {
2.      /** Called when the activity is first created. */
3.      private TextView resultTextView;
4.      private EditText qrStrEditText;
5.      private ImageView qrImgImageView;
6.     
7.      @Override
8.      publicvoid onCreate(Bundle savedInstanceState) {
9.          super.onCreate(savedInstanceState);
10.          setContentView(R.layout.main);
11.         
12.          resultTextView = (TextView) this.findViewById(R.id.tv_scan_result);
13.          qrStrEditText = (EditText) this.findViewById(R.id.et_qr_string);
14.          qrImgImageView = (ImageView) this.findViewById(R.id.iv_qr_image);
15.         
16.          Button scanBarCodeButton = (Button) this.findViewById(R.id.btn_scan_barcode);
17.          scanBarCodeButton.setOnClickListener(new OnClickListener() {
18.             
19.              @Override
20.              publicvoid onClick(View v) {
21.                  //打开扫描界面扫描条形码或二维码
22.                  Intent openCameraIntent = new
Intent(BarCodeTestActivity.this,CaptureActivity.class);
23.                  startActivityForResult(openCameraIntent, 0);
24.              }
25.          });
26.         
27.          Button generateQRCodeButton = (Button) this.findViewById(R.id.btn_add_qrcode);
28.          generateQRCodeButton.setOnClickListener(new OnClickListener() {
29.             
30.              @Override
31.              publicvoid onClick(View v) {
32.                  try {
33.                      String contentString = qrStrEditText.getText().toString();
34.                      if (!contentString.equals("")) {
35.                          //根据字符串生成二维码图片并显示在界面上,第二个参数为图片的大小(350*350)
36.                          Bitmap qrCodeBitmap = EncodingHandler.createQRCode(contentString, 350);
37.                          qrImgImageView.setImageBitmap(qrCodeBitmap);
38.                      }else {
39.                          Toast.makeText(BarCodeTestActivity.this, "Text can not be empty",
Toast.LENGTH_SHORT).show();
40.                      }
41.                     
42.                  } catch (WriterException e) {
43.                      // TODO Auto-generated catch block
44.                      e.printStackTrace();
45.                  }
46.              }
47.          });
48.      }
49.
50.      @Override
51.      protectedvoid onActivityResult(int requestCode, int resultCode, Intent data) {
52.          super.onActivityResult(requestCode, resultCode, data);
53.          //处理扫描结果(在界面上显示)
54.          if (resultCode == RESULT_OK) {
55.              Bundle bundle = data.getExtras();
56.              String scanResult = bundle.getString("result");
57.              resultTextView.setText(scanResult);
58.          }
59.      }
60.  }
其中生成二维码图片的代码在EncodingHandler . jav a中:
1.  publicfinalclass EncodingHandler {
2.      privatestaticfinalint BLACK = 0xff000000;
3.     
4.      publicstatic Bitmap createQRCode(String str,int widthAndHeight) throws WriterException {
5.          Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>(); 
6.          hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
7.          BitMatrix matrix = new MultiFormatWriter().encode(str,
8.                  BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
9.          int width = matrix.getWidth();
10.          int height = matrix.getHeight();
11.          int[] pixels = newint[width * height];
12.         
13.          for (int y = 0; y < height; y++) {
14.              for (int x = 0; x < width; x++) {
15.                  if (matrix.get(x, y)) {
16.                      pixels[y * width + x] = BLACK;
17.                  }
18.              }
19.          }
20.          Bitmap bitmap = Bitmap.createBitmap(width, height,
21.                  Bitmap.Config.ARGB_8888);
22.          bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
23.          return bitmap;
24.      }
25.  }
26.
最后是在哪里对扫描结果进行解码,进入C apt ur eAc t iv it y . jav a找到下面这个方法便可以对自己对结果进行操作:
1.  /**
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();
4. Java端编码演示
在Java端上实现条形码(E A N-13)和二维码(QRCode) 的编码和解码的示例,以供大家参考,用到了源码中c ore和j avase下面的相关源代
码,附件提供自己编译之后的l i b包:
zxi ng. j ar
zxi ng-j 2se. j ar
有关各种手机系统的应用,有兴趣的朋友可以下载官方源码包,包下有具体详细的应用介绍。
1)二维码(QRCode)的编码和解码演示:
编码示例:
1.  package michael.zxing;
2.
3.  import java.io.File;
4.  import java.util.Hashtable;
5.
6.  import com.google.zxing.BarcodeFormat;
7.  import com.google.zxing.EncodeHintType;
8.  import com.google.zxing.MultiFormatWriter;
9.  import com.google.zxing.client.j2se.MatrixToImageWriter;
10.  import com.google.zxing.common.BitMatrix;
11.  import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
12.
13.  /**
14.  * @blog http://sjsky.iteye.com
15.  * @author Michael
16.  */
17.  publicclass ZxingEncoderHandler {
18.
19.      /**
20.       * 编码
21.       * @param contents
22.       * @param width
23.       * @param height
24.       * @param imgPath
25.       */
26.      publicvoid encode(String contents, int width, int height, String imgPath) {
27.          Hashtable<Object, Object> hints = new Hashtable<Object, Object>();
28.          // 指定纠错等级
29.          hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.L);
30.          // 指定编码格式
31.          hints.put(EncodeHintType.CHARACTER_SET, "GBK");
32.          try {
33.              BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,
34.                      BarcodeFormat.QR_CODE, width, height, hints);
35.
36.              MatrixToImageWriter
37.                      .writeToFile(bitMatrix, "png", new File(imgPath));
38.
39.          } catch (Exception e) {
40.              e.printStackTrace();
41.          }
42.      }
43.
44.      /**
45.       * @param args
46.       */
47.      publicstaticvoid main(String[] args) {
48.          String imgPath = "d:/1.png";
49.          String contents = "Hello Word!";
50.          int width = 300, height = 300;
51.          ZxingEncoderHandler handler = new ZxingEncoderHandler();
52.          handler.encode(contents, width, height, imgPath);
53.      }
54.  }
运行后生成的二维码图片如下:
用手机的二维码扫描软件(本人用的:androi d 快拍二维码 )来测试下,识别成功的截图如下:
解码示例:
1.  package michael.zxing;
2.
3.  import java.awt.image.BufferedImage;
4.  import java.io.File;
5.  import java.util.Hashtable;
6.
7.  import javax.imageio.ImageIO;
8.
9.  import com.google.zxing.BinaryBitmap;
10.  import com.google.zxing.DecodeHintType;
11.  import com.google.zxing.LuminanceSource;
12.  import com.google.zxing.MultiFormatReader;
13.  import com.google.zxing.Result;
14.  import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
15.  import com.google.zxing.common.HybridBinarizer;
16.
17.  /**
18.  * @blog http://sjsky.iteye.com
19.  * @author Michael
20.  */
21.  publicclass ZxingDecoderHandler {
22.
23.      /**
24.       * @param imgPath
25.       * @return String
26.       */
27.      public String decode(String imgPath) {
28.          BufferedImage image = null;
29.          Result result = null;
30.          try {
31.              image = ImageIO.read(new File(imgPath));
32.              if (image == null) {
33.                  System.out.println("the decode image may be not exit.");
34.              }
35.              LuminanceSource source = new BufferedImageLuminanceSource(image);
36.              BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
37.
38.              Hashtable<Object, Object> hints = new Hashtable<Object, Object>();
39.              hints.put(DecodeHintType.CHARACTER_SET, "utf-8");
40.
41.              result = new MultiFormatReader().decode(bitmap, hints);
42.              return result.getText();
43.          } catch (Exception e) {
44.              e.printStackTrace();
45.          }
46.          returnnull;
47.      }
48.
49.      /**
50.       * @param args
51.       */
52.      publicstaticvoid main(String[] args) {
53.          String imgPath = "d:/1.png";
54.          ZxingDecoderHandler handler = new ZxingDecoderHandler();
55.          String decodeContent = handler.decode(imgPath);
56.          System.out.println("解码内容如下:");
57.          System.out.println(decodeContent);
58.      }
59.  }

解码内容如下: Hello W or d!
2)条形码(EAN- 13)的编码和解码演示:
编码示例:
1.  package michael.zxing;
2.
3.  import java.io.File;
4.
5.  import com.google.zxing.BarcodeFormat;
6.  import com.google.zxing.MultiFormatWriter;
7.  import com.google.zxing.client.j2se.MatrixToImageWriter;
8.  import com.google.zxing.common.BitMatrix;
9.
10.  /**
11.  * @blog http://sjsky.iteye.com
12.  * @author Michael
13.  */
14.  publicclass ZxingEAN13EncoderHandler {
15.
16.      /**
17.       * 编码
18.       * @param contents
19.       * @param width
20.       * @param height
21.       * @param imgPath
22.       */
23.      publicvoid encode(String contents, int width, int height, String imgPath) {
24.          int codeWidth = 3 + // start guard
25.                  (7 * 6) + // left bars
26.                  5 + // middle guard 
27.                  (7 * 6) + // right bars
28.                  3; // end guard
29.          codeWidth = Math.max(codeWidth, width);
30.          try {
31.              BitMatrix bitMatrix = new MultiFormatWriter().encode(contents,
32.                      BarcodeFormat.EAN_13, codeWidth, height, null);
33.
34.              MatrixToImageWriter
35.                      .writeToFile(bitMatrix, "png", new File(imgPath));
36.
37.          } catch (Exception e) {
38.              e.printStackTrace();
39.          }
40.      }
41.
42.      /**
43.       * @param args
44.       */
45.      publicstaticvoid main(String[] args) {
46.          String imgPath = "d:/2.png";
47.          // 益达无糖口香糖的条形码
48.          String contents = "6923450657713";
49.
50.          int width = 105, height = 50;
51.          ZxingEAN13EncoderHandler handler = new ZxingEAN13EncoderHandler();
52.          handler.encode(contents, width, height, imgPath);
53.      }
54.  }
运行后生成条形码图片如下:

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

解码示例:
1.  package michael.zxing;
2.
3.  import java.awt.image.BufferedImage;
4.  import java.io.File;
5.
6.  import javax.imageio.ImageIO;
7.
8.  import com.google.zxing.BinaryBitmap;
9.  import com.google.zxing.LuminanceSource;
10.  import com.google.zxing.MultiFormatReader;
11.  import com.google.zxing.Result;
12.  import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
13.  import com.google.zxing.common.HybridBinarizer;
14.
15.  /**
16.  * @blog http://sjsky.iteye.com
17.  * @author Michael
18.  */
19.  publicclass ZxingEAN13DecoderHandler {
20.
21.      /**
22.       * @param imgPath
23.       * @return String
24.       */
25.      public String decode(String imgPath) {
26.          BufferedImage image = null;
27.          Result result = null;
28.          try {
29.              image = ImageIO.read(new File(imgPath));
30.              if (image == null) {
31.                  System.out.println("the decode image may be not exit.");
32.              }
33.              LuminanceSource source = new BufferedImageLuminanceSource(image);
34.              BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
35.
36.              result = new MultiFormatReader().decode(bitmap, null);
37.              return result.getText();
38.          } catch (Exception e) {
39.              e.printStackTrace();
40.          }
41.          returnnull;
42.      }
43.
44.      /**
45.       * @param args
46.       */
47.      publicstaticvoid main(String[] args) {
48.          String imgPath = "d:/2.png";
49.          ZxingEAN13DecoderHandler handler = new ZxingEAN13DecoderHandler();
50.          String decodeContent = handler.decode(imgPath);
51.          System.out.println("解码内容如下:");
52.          System.out.println(decodeContent);
53.      }
54.  }
解码内容如下:  6 9 2 3 4 5 0 6 5 7 7 1 3
5.源码说明和下载
官方例子:
BarcodeScanner (Barcode Scanner 4.31 for Androi d Feat ured 必须先将此apk安装才可以运行ZXi ngTes t 项目)
ZXi ngTes t  (androi d端调用BarcodeScanner测试例子)
简化例子:
BarCodeTes t  (androi d端扫描和解码精简例子)
QRcode (java端扫描和解码例子)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章