Android 使用ZXing库识别图片上的二维码:
1. EncodingHandler.java 文件:
public final class EncodingHandler {
private static final int BLACK = 0xff000000;
public static Bitmap createQRCode(String str,int widthAndHeight) throws WriterException {
Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
BitMatrix matrix = new MultiFormatWriter().encode(str,
BarcodeFormat.QR_CODE, widthAndHeight, widthAndHeight);
int width = matrix.getWidth();
int height = matrix.getHeight();
int[] pixels = new int[width * height];
for (int y = 0; y < height; y++) {
for (int x = 0; x < width; x++) {
if (matrix.get(x, y)) {
pixels[y * width + x] = BLACK;
}
}
}
Bitmap bitmap = Bitmap.createBitmap(width, height,
Bitmap.Config.ARGB_8888);
bitmap.setPixels(pixels, 0, width, 0, 0, width, height);
return bitmap;
}
}
2. RGBLuminanceSource 类继承ZXing库中的LuminanceSource类:
public class RGBLuminanceSource extends LuminanceSource {
private final byte[] luminances;
private final int dataWidth;
private final int dataHeight;
private final int left;
private final int top;
public RGBLuminanceSource(Bitmap bitmap) {
super(bitmap.getWidth(), bitmap.getHeight());
// TODO Auto-generated constructor stub
int width = bitmap.getWidth();
int height = bitmap.getHeight();
int[] pixels = new int[width * height];
bitmap.getPixels(pixels, 0, bitmap.getWidth(), 0, 0, bitmap.getWidth(), bitmap.getHeight());
dataWidth = width;
dataHeight = height;
left = 0;
top = 0;
// In order to measure pure decoding speed, we convert the entire image to a greyscale array
// up front, which is the same as the Y channel of the YUVLuminanceSource in the real app.
luminances = new byte[width * height];
for (int y = 0; y < height; y++) {
int offset = y * width;
for (int x = 0; x < width; x++) {
int pixel = pixels[offset + x];
int r = (pixel >> 16) & 0xff;
int g = (pixel >> 8) & 0xff;
int b = pixel & 0xff;
if (r == g && g == b) {
// Image is already greyscale, so pick any channel.
luminances[offset + x] = (byte) r;
} else {
// Calculate luminance cheaply, favoring green.
luminances[offset + x] = (byte) ((r + g + g + b) >> 2);
}
}
}
}
@Override
public byte[] getMatrix() {
// TODO Auto-generated method stub
int width = getWidth();
int height = getHeight();
// If the caller asks for the entire underlying image, save the copy and give them the
// original data. The docs specifically warn that result.length must be ignored.
if (width == dataWidth && height == dataHeight) {
return luminances;
}
int area = width * height;
byte[] matrix = new byte[area];
int inputOffset = top * dataWidth + left;
// If the width matches the full width of the underlying data, perform a single copy.
if (width == dataWidth) {
System.arraycopy(luminances, inputOffset, matrix, 0, area);
return matrix;
}
// Otherwise copy one cropped row at a time.
byte[] rgb = luminances;
for (int y = 0; y < height; y++) {
int outputOffset = y * width;
System.arraycopy(rgb, inputOffset, matrix, outputOffset, width);
inputOffset += dataWidth;
}
return matrix;
}
@Override
public byte[] getRow(int y, byte[] row) {
// TODO Auto-generated method stub
if (y < 0 || y >= getHeight()) {
throw new IllegalArgumentException("Requested row is outside the image: " + y);
}
int width = getWidth();
if (row == null || row.length < width) {
row = new byte[width];
}
int offset = (y + top) * dataWidth + left;
System.arraycopy(luminances, offset, row, 0, width);
return row;
}
}
2,识别图片二维码的代码:
Hashtable<DecodeHintType, String> hints = new Hashtable<DecodeHintType, String>();
hints.put(DecodeHintType.CHARACTER_SET, "utf-8"); // 设置二维码内容的编码
BitmapFactory.Options options = new BitmapFactory.Options();
options.inJustDecodeBounds = true; // 先获取原大小
Bitmap scanBitmap = BitmapFactory.decodeFile("/mnt/sdcard/temp_QRCode.png", options);
options.inJustDecodeBounds = false; // 获取新的大小
int sampleSize = (int) (options.outHeight / (float) 200);
if (sampleSize <= 0)
sampleSize = 1;
options.inSampleSize = sampleSize;
scanBitmap = BitmapFactory.decodeFile("/mnt/sdcard/temp_QRCode.png", options);
RGBLuminanceSource source = new RGBLuminanceSource(scanBitmap);
BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
QRCodeReader reader = new QRCodeReader();
try {
Result result = reader.decode(bitmap1, hints);
if (result != null) {
String data = result.toString();
Toast.makeText(MainActivity.this, "Data= " + data, Toast.LENGTH_LONG).show();
}
} catch (NotFoundException e) {
e.printStackTrace();
} catch (ChecksumException e) {
e.printStackTrace();
} catch (FormatException e) {
e.printStackTrace();
}