有的應用程式需要將一段字符加密為一個二維條碼,我們可以用一個現成的開源程式碼來幫我們搞定二維碼,這個框架就是Google 自家的Zxing,它已經封裝好了對一維碼、二維碼的編碼和解碼的功能。
ZXing是一個用Java實作而且OpenSource專門用來判斷條碼的library,所以如果要自行開發相關判斷條碼功能的話,可以直接呼叫ZXing幫忙處理。為了不要依賴外部軟體,我將會介紹直接在你app內嵌Zxing條碼掃描、解碼功能的相關API。
在本篇中,以快速實現效果為準,並不會從原始碼編譯開始(因為那又要用到類似make的工具ant) ,這個ant我自己玩了幾個小時也沒玩出名堂,每次編都出現詭異的錯誤。
所以我會建議各位新手直接下載github上面做好的.jar檔案,直接匯入eclipse,直接開始使用。
然後我用的是2.2版的,最新的3.0不知道為什麼會出現VerifyError的錯誤,傻眼...
package com.example.qrcode_and_barcode; | |
import java.util.HashMap; | |
import android.app.Activity; | |
import android.graphics.Bitmap; | |
import android.graphics.drawable.BitmapDrawable; | |
import android.os.Bundle; | |
import android.widget.ImageView; | |
import android.widget.TextView; | |
import com.google.zxing.BarcodeFormat; | |
import com.google.zxing.BinaryBitmap; | |
import com.google.zxing.ChecksumException; | |
import com.google.zxing.EncodeHintType; | |
import com.google.zxing.FormatException; | |
import com.google.zxing.LuminanceSource; | |
import com.google.zxing.MultiFormatReader; | |
import com.google.zxing.MultiFormatWriter; | |
import com.google.zxing.NotFoundException; | |
import com.google.zxing.RGBLuminanceSource; | |
import com.google.zxing.Reader; | |
import com.google.zxing.Result; | |
import com.google.zxing.WriterException; | |
import com.google.zxing.common.BitMatrix; | |
import com.google.zxing.common.HybridBinarizer; | |
public class MainActivity extends Activity | |
{ | |
ImageView qrcode; | |
ImageView barcode; | |
TextView bar; | |
TextView qr; | |
@Override | |
protected void onCreate(Bundle savedInstanceState) | |
{ | |
super.onCreate(savedInstanceState); | |
setContentView(R.layout.activity_main); | |
qrcode = (ImageView) findViewById(R.id.qrcode); | |
barcode = (ImageView) findViewById(R.id.barcode); | |
qr = (TextView) findViewById(R.id.qr); | |
bar = (TextView) findViewById(R.id.bar); | |
try | |
{ | |
String _要編碼的內容 = "0123456789"; | |
qrcode.setImageBitmap(encodeAsBitmap(_要編碼的內容, BarcodeFormat.QR_CODE, 300, 150)); | |
barcode.setImageBitmap(encodeAsBitmap(_要編碼的內容, BarcodeFormat.CODE_39, 400, 70)); | |
String barString = decode(getBitmapFromImageView(barcode)); | |
String qrString = decode(getBitmapFromImageView(qrcode)); | |
qr.setText(qrString); | |
bar.setText(barString); | |
} | |
catch (WriterException e) | |
{ | |
// TODO 自動產生的 catch 區塊 | |
e.printStackTrace(); | |
} | |
} | |
private Bitmap getBitmapFromImageView(ImageView v) | |
{ | |
final BitmapDrawable bitmapDrawable = (BitmapDrawable) v.getDrawable(); | |
return bitmapDrawable.getBitmap(); | |
} | |
private String decode(Bitmap bMap) | |
{ | |
String contents = null; | |
int w = bMap.getWidth(); | |
int h = bMap.getHeight(); | |
int[] intArray = new int[w * h]; | |
//copy pixel data from the Bitmap into the 'intArray' array | |
bMap.getPixels(intArray, 0, bMap.getWidth(), 0, 0, bMap.getWidth(), bMap.getHeight()); | |
LuminanceSource source = new RGBLuminanceSource(bMap.getWidth(), bMap.getHeight(), intArray); | |
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source)); | |
// use this otherwise ChecksumException | |
Reader reader = new MultiFormatReader(); | |
try | |
{ | |
Result result = reader.decode(bitmap); | |
contents = result.getText(); | |
} | |
catch (NotFoundException e) | |
{ | |
e.printStackTrace(); | |
} | |
catch (ChecksumException e) | |
{ | |
e.printStackTrace(); | |
} | |
catch (FormatException e) | |
{ | |
e.printStackTrace(); | |
} | |
return contents; | |
} | |
public static Bitmap encodeAsBitmap(String contents, BarcodeFormat format, int desiredWidth, int desiredHeight) throws WriterException | |
{ | |
if (contents.length() == 0) return null; | |
final int WHITE = 0xFFFFFFFF; | |
final int BLACK = 0xFF000000; | |
HashMap<EncodeHintType, String> hints = null; | |
String encoding = null; | |
for (int i = 0; i < contents.length(); i++) | |
{ | |
if (contents.charAt(i) > 0xFF) | |
{ | |
encoding = "UTF-8"; | |
break; | |
} | |
} | |
if (encoding != null) | |
{ | |
hints = new HashMap<EncodeHintType, String>(2); | |
hints.put(EncodeHintType.CHARACTER_SET, encoding); | |
} | |
MultiFormatWriter writer = new MultiFormatWriter(); | |
BitMatrix result = writer.encode(contents, format, desiredWidth, desiredHeight, hints); | |
int width = result.getWidth(); | |
int height = result.getHeight(); | |
int[] pixels = new int[width * height]; | |
for (int y = 0; y < height; y++) | |
{ | |
int offset = y * width; | |
for (int x = 0; x < width; x++) | |
{ | |
pixels[offset + x] = result.get(x, y) ? BLACK : WHITE; | |
} | |
} | |
Bitmap bitmap = Bitmap.createBitmap(width, height, Bitmap.Config.ARGB_8888); | |
bitmap.setPixels(pixels, 0, width, 0, 0, width, height); | |
return bitmap; | |
} | |
} |