2016年8月30日 星期二

產生和解碼二維條碼(QRCode)與一維條碼

Ref : http://www.unood.me/2013/07/android-qrcodecode39.html

有的應用程式需要將一段字符加密為一個二維條碼,我們可以用一個現成的開源程式碼來幫我們搞定二維碼,這個框架就是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;
}
}