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