Android之zxing二维码生成于识别

原文地址:http://blog.csdn.net/xll712/article/details/49821095

前言

二维码的应用现在随处可见,最近在弄即时通信软件,所以想添加二维码名片功能,所以就大概搜索了一下,目前二维码识别与生成比较常用的就是google老大的zxing,比较成熟、稳定,推荐使用。

zxing的引入可以采用源码或jar包引入的方式:

1、以源码引入 
zxing的源码在github上的地址为:https://github.com/zxing/zxing,只需要下载core下面的源码就行;

2、以jar包方式引入 
jar包下载地址为: 
http://www.java2s.com/Code/Jar/z/Downloadzxing20corejar.htm,同样只需要下载core.jar就行;

生成二维码的方法很简单,如下面代码所示

// 生成QR图
    private void createImage(String content) {        try {            // 把输入的文本转为二维码
            Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");

            BitMatrix bitMatrix = new QRCodeWriter().encode(content,
                    BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);            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 = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT,
                    Bitmap.Config.ARGB_8888);

            bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT);            if (bitmap != null) {
                resultImageView.setImageBitmap(bitmap);
            }

        } catch (WriterException e) {
            e.printStackTrace();
        }
    }12345678910111213141516171819202122232425262728293031323334

获取二维码图片的内容

获取内容方面比较麻烦,zxing中的LuminanceSource不能直接使用,所以需要写一个扩展的子类,用以专门解析二维码图片中的内容,由于上面生产的图片内容采用的是json数据的格式,所以在获取内容时也需要按json解析一下; 
我封装的LuminanceSource的子类为RGBLuminanceSource,代码如下:

package com.lanou.zxingdemo;import java.io.FileNotFoundException;import android.graphics.Bitmap;import android.graphics.BitmapFactory;import com.google.zxing.LuminanceSource;public class RGBLuminanceSource extends LuminanceSource {
    private final byte[] luminances;    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);        //为了测量纯解码速度,我们将整个图像灰度阵列前面,这是一样的通道
        // YUVLuminanceSource在现实应用。
        //得到像素大小的字节数
        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) {
                    luminances[offset + x] = (byte) r;
                } 
                //其它情况字节空间对应赋值为:
                else {  
                    luminances[offset + x] = (byte) ((r + g + g + b) >> 2);
                }
            }
        }
    }    public RGBLuminanceSource(String path) throws FileNotFoundException {        this(loadBitmap(path));
    }    @Override
    public byte[] getMatrix() {        return luminances;
    }    @Override
    public byte[] getRow(int arg0, byte[] arg1) {        if (arg0 < 0 || arg0 >= getHeight()) {            throw new IllegalArgumentException(                    "Requested row is outside the image: " + arg0);
        }        int width = getWidth();        if (arg1 == null || arg1.length < width) {
            arg1 = new byte[width];
        }
        System.arraycopy(luminances, arg0 * width, arg1, 0, width);        return arg1;
    }    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;
    }
}12345678910111213141516171819202122232425262728293031323334353637383940414243444546474849505152535455565758596061626364656667686970717273747576

解析二维码内容的方法,代码如下:

// 解析QR图片
    private void scanningImage() {
        BitmapDrawable drawable = (BitmapDrawable) resultImageView.getDrawable();        if (drawable == null) {
            Toast.makeText(this, "还没有图片,请先生成", Toast.LENGTH_LONG).show();            return;
        }
        Bitmap bitmap = drawable.getBitmap();

        Map<DecodeHintType, String> hints = new HashMap<DecodeHintType, String>();
        hints.put(DecodeHintType.CHARACTER_SET, "utf-8");        // 获得待解析的图片
        RGBLuminanceSource source = new RGBLuminanceSource(bitmap);
        BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
        QRCodeReader reader = new QRCodeReader();
        Result result;        try {
            result = reader.decode(bitmap1, hints);
            JSONObject json = new JSONObject(result.getText());            // 得到解析后的文字
            String str ="  name: "+json.getString("name")+"  \n\r title: "+json.getString("title")+" \n\r url: "+json.getString("url");
            resultTv.setText(str);

        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (ChecksumException e) {
            e.printStackTrace();
        } catch (FormatException e) {
            e.printStackTrace();
        } catch (JSONException e) {            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }1234567891011121314151617181920212223242526272829303132333435

本demo就建了两个java类(MainActivity,RGBLuminanceSource),一个布局文件(activity_main.xml),引入了一个jar包(zxing-core-2.0.jar),完整代码如下:

MainActivity

package com.lanou.zxingdemo;import java.util.HashMap;import java.util.Hashtable;import java.util.Map;import org.json.JSONException;import org.json.JSONObject;import com.google.zxing.BarcodeFormat;import com.google.zxing.BinaryBitmap;import com.google.zxing.ChecksumException;import com.google.zxing.DecodeHintType;import com.google.zxing.EncodeHintType;import com.google.zxing.FormatException;import com.google.zxing.NotFoundException;import com.google.zxing.Result;import com.google.zxing.WriterException;import com.google.zxing.common.BitMatrix;import com.google.zxing.common.HybridBinarizer;import com.google.zxing.qrcode.QRCodeReader;import com.google.zxing.qrcode.QRCodeWriter;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.ImageView;import android.widget.TextView;import android.widget.Toast;public class MainActivity extends Activity implements OnClickListener {
    private Button encodeBtn,decodeBtn;
    private final int QR_WIDTH = 200, QR_HEIGHT = 200;
    private ImageView resultImageView;
    private TextView resultTv;

    @Override
    protected void onCreate(Bundle savedInstanceState) {
        // TODO Auto-generated method stub
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        initView();
    }

    private void initView() {
        encodeBtn = (Button) findViewById(R.id.encodeBtn);
        decodeBtn = (Button) findViewById(R.id.decodeBtn);
        encodeBtn.setOnClickListener(this);
        decodeBtn.setOnClickListener(this);

        resultImageView = (ImageView) findViewById(R.id.resultImageView);
        resultTv = (TextView) findViewById(R.id.resultTv);

    }

    @Override
    public void onClick(View v) {
        switch (v.getId()) {
        case R.id.encodeBtn:

            JSONObject json = new JSONObject(); 
            try {
                json.put("name", "xiaoxiao");
                json.put("url", "http://www.baidu.com");
                json.put("title", "title");

                createImage(json.toString());

            } catch (JSONException e) {
                // TODO Auto-generated catch block
                e.printStackTrace();
            }            break;
        case R.id.decodeBtn:
            scanningImage();
            break;
        }
    }

    // 生成QR图
    private void createImage(String content) {
        try {
            // 把输入的文本转为二维码
            Hashtable<EncodeHintType, String> hints = new Hashtable<EncodeHintType, String>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");

            BitMatrix bitMatrix = new QRCodeWriter().encode(content,
                    BarcodeFormat.QR_CODE, QR_WIDTH, QR_HEIGHT, hints);

            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 = Bitmap.createBitmap(QR_WIDTH, QR_HEIGHT,
                    Bitmap.Config.ARGB_8888);

            bitmap.setPixels(pixels, 0, QR_WIDTH, 0, 0, QR_WIDTH, QR_HEIGHT);
            if (bitmap != null) {
                resultImageView.setImageBitmap(bitmap);
            }

        } catch (WriterException e) {
            e.printStackTrace();
        }
    }

    // 解析QR图片
    private void scanningImage() {
        BitmapDrawable drawable = (BitmapDrawable) resultImageView.getDrawable();
        if (drawable == null) {
            Toast.makeText(this, "还没有图片,请先生成", Toast.LENGTH_LONG).show();
            return;
        }
        Bitmap bitmap = drawable.getBitmap();

        Map<DecodeHintType, String> hints = new HashMap<DecodeHintType, String>();
        hints.put(DecodeHintType.CHARACTER_SET, "utf-8");

        // 获得待解析的图片
        RGBLuminanceSource source = new RGBLuminanceSource(bitmap);
        BinaryBitmap bitmap1 = new BinaryBitmap(new HybridBinarizer(source));
        QRCodeReader reader = new QRCodeReader();
        Result result;
        try {
            result = reader.decode(bitmap1, hints);
            JSONObject json = new JSONObject(result.getText());
            // 得到解析后的文字
            String str ="  name: "+json.getString("name")+"  \n\r title: "+json.getString("title")+" \n\r url: "+json.getString("url");
            resultTv.setText(str);

        } catch (NotFoundException e) {
            e.printStackTrace();
        } catch (ChecksumException e) {
            e.printStackTrace();
        } catch (FormatException e) {
            e.printStackTrace();
        } catch (JSONException e) {
            // TODO Auto-generated catch block
            e.printStackTrace();
        }
    }

}123456789101112131415161718192021222324252627282930313233343536373839404142434445464748495051525354555657585960616263646566676869707172737475767778798081828384858687888990919293949596979899100101102103104105106107108109110111112113114115116117118119120121122123124125126127128129130131132133134135136137138139140141142143144145146147148149150151152153154155156

activity_main.xml

<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"
    xmlns:tools="http://schemas.android.com/tools"
    android:layout_width="match_parent"
    android:layout_height="match_parent"
    tools:context="${relativePackage}.${activityClass}" >

    <LinearLayout        android:id="@+id/linear"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:orientation="horizontal" >

        <Button            android:id="@+id/encodeBtn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="生成二维码图片" />

        <Button            android:id="@+id/decodeBtn"
            android:layout_width="0dp"
            android:layout_height="wrap_content"
            android:layout_weight="1"
            android:text="解析二维码图片中的内容" />
    </LinearLayout>

    <ImageView        android:id="@+id/resultImageView"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/linear" />

    <TextView        android:id="@+id/resultTv"
        android:layout_marginTop="30dp"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_below="@+id/resultImageView" /></RelativeLayout>1234567891011121314151617181920212223242526272829303132333435363738394041

代码结构:

这里写图片描述

运行效果:

这里写图片描述


转载于:https://my.oschina.net/u/2531415/blog/661588

  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值