二維碼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端掃描和解碼例子)
發表評論
所有評論
還沒有人評論,想成為第一個評論的人麼? 請在上方評論欄輸入並且點擊發布.
相關文章