Android二维码的生成与解析
jopen
10年前
本示例演示使用文本生成对应的二维码图片,和解析二维码图片的内容。代码如下:
MainActivity:
package com.home.testqrcode; import java.util.HashMap; import java.util.Hashtable; import java.util.Map; import android.app.Activity; import android.graphics.Bitmap; import android.graphics.drawable.BitmapDrawable; import android.os.Bundle; import android.view.View; import android.view.View.OnClickListener; import android.widget.Button; import android.widget.EditText; import android.widget.ImageView; import android.widget.TextView; import android.widget.Toast; import com.google.zxing.BarcodeFormat; import com.google.zxing.BinaryBitmap; import com.google.zxing.DecodeHintType; import com.google.zxing.EncodeHintType; import com.google.zxing.Result; import com.google.zxing.WriterException; import com.google.zxing.client.androidtest.RGBLuminanceSource; import com.google.zxing.common.BitMatrix; import com.google.zxing.common.HybridBinarizer; import com.google.zxing.qrcode.QRCodeReader; import com.google.zxing.qrcode.QRCodeWriter; public class MainActivity extends Activity implements OnClickListener { private Button generateBtn; private Button decodeQRCodeBtn; private ImageView imageView; private TextView textView; private EditText contentText; private static int QR_WIDTH = 400; private static int QR_HEIGHT = 400; @Override protected void onCreate(Bundle savedInstanceState) { super.onCreate(savedInstanceState); setContentView(R.layout.main); initWidget(); } private void initWidget() { generateBtn = (Button) findViewById(R.id.main_btn_generateQRCode); generateBtn.setOnClickListener(this); decodeQRCodeBtn = (Button) findViewById(R.id.main_btn_decodeQRCode); decodeQRCodeBtn.setOnClickListener(this); imageView = (ImageView) findViewById(R.id.main_iv); textView = (TextView) findViewById(R.id.main_tv); contentText = (EditText) findViewById(R.id.main_et); } @Override public void onClick(View v) { if (v == generateBtn) { String text = contentText.getText().toString(); if ("".equals(text) || null == text) { Toast.makeText(this, "请输入内容", Toast.LENGTH_SHORT).show(); return; } Bitmap bitmap = createBitmap(text); if (bitmap != null) { imageView.setImageBitmap(bitmap); } } else if (v == decodeQRCodeBtn) { String content = readImage(imageView); textView.setText(content); } } /** * 生成二维码图片 * * @return */ private Bitmap createBitmap(String text) { Bitmap bitmap = null; try { Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>(); hints.put(EncodeHintType.CHARACTER_SET, "utf-8"); BitMatrix bitMatrix = new QRCodeWriter().encode(text, BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints); // QRCodeWriter writer = new QRCodeWriter(); // // 把输入的文本转为二维码 // BitMatrix bitMatrix = writer.encode(text, BarcodeFormat.QR_CODE, // QR_WIDTH, QR_HEIGHT); int[] pixels = new int[QR_WIDTH * QR_HEIGHT]; for (int y = 0; y < QR_HEIGHT; y++) { for (int x = 0; x < QR_WIDTH; x++) { if (bitMatrix.get(x, y)) { pixels[y * QR_WIDTH + x] = 0xff000000; } else { pixels[y * QR_WIDTH + x] = 0xffffffff; } } } bitmap = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT, Bitmap.Config.ARGB_8888); bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT); } catch (WriterException e) { e.printStackTrace(); } return bitmap; } /** * 解析QR图内容 * * @param imageView * @return */ private String readImage(ImageView imageView) { String content = null; Map<DecodeHintType, String> hints = new HashMap<DecodeHintType, String>(); hints.put(DecodeHintType.CHARACTER_SET, "utf-8"); // 获得待解析的图片 Bitmap bitmap = ((BitmapDrawable) imageView.getDrawable()).getBitmap(); RGBLuminanceSource source = new RGBLuminanceSource(bitmap); BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source)); QRCodeReader reader = new QRCodeReader(); try { Result result = reader.decode(bitmap1, hints); // 得到解析后的文字 content = result.getText(); } catch (Exception e) { e.printStackTrace(); } return content; } }
RGBLuminanceSource:
package com.google.zxing.client.androidtest; import com.google.zxing.LuminanceSource; import android.graphics.Bitmap; import android.graphics.BitmapFactory; import java.io.FileNotFoundException; /** * This class is used to help decode images from files which arrive as RGB data * from Android bitmaps. It does not support cropping or rotation. * * @author dswitkin@google.com (Daniel Switkin) */ public final class RGBLuminanceSource extends LuminanceSource { private final byte[] luminances; public RGBLuminanceSource(String path) throws FileNotFoundException { this(loadBitmap(path)); } public RGBLuminanceSource(Bitmap bitmap) { super(bitmap.getWidth(), bitmap.getHeight()); int width = bitmap.getWidth(); int height = bitmap.getHeight(); int[] pixels = new int[width * height]; bitmap.getPixels(pixels, 0, width, 0, 0, width, height); // 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[] getRow(int y, byte[] row) { 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]; } System.arraycopy(luminances, y * width, row, 0, width); return row; } // Since this class does not support cropping, the underlying byte array // already contains // exactly what the caller is asking for, so give it to them without a copy. @Override public byte[] getMatrix() { return luminances; } private static Bitmap loadBitmap(String path) throws FileNotFoundException { Bitmap bitmap = BitmapFactory.decodeFile(path); if (bitmap == null) { throw new FileNotFoundException("Couldn't open " + path); } return bitmap; } }
main.xml:
<LinearLayout xmlns:android="http://schemas.android.com/apk/res/android" android:layout_width="match_parent" android:layout_height="match_parent" android:gravity="center_horizontal" android:orientation="vertical" > <EditText android:id="@+id/main_et" android:layout_width="match_parent" android:layout_height="wrap_content" /> <Button android:id="@+id/main_btn_generateQRCode" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="使用文本生成二维码" /> <Button android:id="@+id/main_btn_decodeQRCode" android:layout_width="match_parent" android:layout_height="wrap_content" android:text="解析二维码内容" /> <ImageView android:id="@+id/main_iv" android:layout_width="wrap_content" android:layout_height="wrap_content" /> <TextView android:id="@+id/main_tv" android:layout_width="match_parent" android:layout_height="wrap_content" android:layout_marginTop="20dp" android:gravity="center_horizontal" android:textSize="20sp" /> </LinearLayout>