带你玩转二维码

  什么是二维码:

        二维条码/二维码(2-dimensional bar code)是用某种特定的几何图形按一定规律在平面(二维方向上)分布的黑白相间的图形记录数据符号信息的;在代码编制上巧妙地利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图象输入设备或光电扫描设备自动识读以实现信息自动处理:它具有条码技术的一些共性:每种码制有其特定的字符集;每个字符占有一定的宽度;具有一定的校验功能等。同时还具有对不同行的信息自动识别功能、及处理图形旋转变化点。

  现在二维码在我们生活中到处可见,各种APP的开发当然少不了二维码,那么下面我来简绍下二维码的使用.

 

对于二维码扫描我们使用的是google的开源框架Zxing,我们可以去http://code.google.com/p/zxing/下载源码和Jar包

首先将源码和jar包导入我们的项目中,结构如下:


这里我们需要在功能清单里进行一系列的权限注册

<?xml version="1.0" encoding="utf-8"?>
<manifest xmlns:android="http://schemas.android.com/apk/res/android"
    package="com.hsj.example.zxingscannerdemo03">

   <span style="color:#ff0000;"> <uses-permission android:name="android.permission.VIBRATE" />
    <uses-permission android:name="android.permission.CAMERA" />
    <uses-feature android:name="android.hardware.camera" />
    <uses-feature android:name="android.hardware.camera.autofocus" /></span>

    <application
        android:allowBackup="true"
        android:icon="@mipmap/ic_launcher"
        android:label="@string/app_name"
        android:supportsRtl="true"
        android:theme="@style/AppTheme">
        <activity android:name=".MainActivity">
            <intent-filter>
                <action android:name="android.intent.action.MAIN" />

                <category android:name="android.intent.category.LAUNCHER" />
            </intent-filter>
        </activity>

        <span style="color:#ff6666;"><!--捕捉Activity -->
        <activity android:name="com.zxing.activity.CaptureActivity"/></span>
    </application>

</manifest>


这里我写了一个小案例来实现二维码的功能

主布局如下:

<?xml version="1.0" encoding="utf-8"?>
<RelativeLayout xmlns:android="http://schemas.android.com/apk/res/android"

    android:layout_width="match_parent"
    android:layout_height="match_parent"
    android:paddingBottom="@dimen/activity_vertical_margin"
    android:paddingLeft="@dimen/activity_horizontal_margin"
    android:paddingRight="@dimen/activity_horizontal_margin"
    android:paddingTop="@dimen/activity_vertical_margin">

    <Button
        android:id="@+id/button_scanner"
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:layout_alignParentLeft="true"
        android:layout_alignParentStart="true"
        android:layout_alignParentTop="true"
        android:layout_marginLeft="68dp"
        android:layout_marginStart="68dp"
        android:text="扫一扫解二维码" />

    <EditText
        android:id="@+id/editText_info"
        android:layout_width="match_parent"
        android:layout_height="wrap_content"
        android:layout_below="@+id/button_scanner"
        android:textSize="10sp"
        android:hint="请输入要生成二维码需要的字符串信息" />

    <Button
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:text="生成二维码"
        android:id="@+id/button_generator"
        android:layout_below="@+id/editText_info"
        android:layout_alignLeft="@+id/button_scanner"
        android:layout_alignStart="@+id/button_scanner" />

    <ImageView
        android:layout_width="wrap_content"
        android:layout_height="wrap_content"
        android:id="@+id/imageView_QuickResponseCode"
        android:layout_below="@+id/button_generator"
        android:layout_alignLeft="@+id/button_generator"
        android:layout_alignStart="@+id/button_generator"
        android:src="@mipmap/ic_launcher" />
</RelativeLayout>

然后mainActivity

public class MainActivity extends AppCompatActivity {

    private Button button_scanner;
    private EditText editText_info;
    private Button button_generator;
    private ImageView imageView_QuickResponseCode;


    @Override
    protected void onCreate(Bundle savedInstanceState) {
        super.onCreate(savedInstanceState);
        setContentView(R.layout.activity_main);
        this.initView();

        this.button_scanner.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                Intent intent=new Intent(MainActivity.this, CaptureActivity.class);
                startActivityForResult(intent,100);
            }
        });

        this.button_generator.setOnClickListener(new View.OnClickListener() {
            @Override
            public void onClick(View v) {
                String content=editText_info.getText().toString();
                if(TextUtils.isEmpty(content)){
                    editText_info.setError("生成二维码的内容不能为空!");
                    editText_info.requestFocus();
                    return;

                }
                //Bitmap bitmap=getQRCode(content,300);
// Bitmap bitmap=generateQRCode(content,300, BitmapFactory.decodeResource(getResources(),R.mipmap.logo),20);
// imageView_QuickResponseCode.setImageBitmap(bitmap);

                //注意:如果中心图片太大,需要设置生成的二维码更大些,否则识别不了
                Bitmap bmp01  = getQRCode(editText_info.getText().toString(), 500);
                Bitmap bmp02 = BitmapFactory.decodeResource(getResources(),R.mipmap.ic_launcher);
                imageView_QuickResponseCode.setImageBitmap(getBmp(bmp01,bmp02));
            }
        });
    }

    /**
     * 合成带头像的二维码
     * @param bmp01:二维码的bitmap
     * @param bmp02:头像的bitmap
     */
    public Bitmap  getBmp(Bitmap bmp01, Bitmap bmp02) {

        if (bmp01 == null) {
            return null;
        }
        int w1 = bmp01.getWidth();
        int h1 = bmp01.getHeight();
        int w2 = bmp02.getWidth();
        int h2 = bmp02.getHeight();


        //圈定一个区域(bmp01的区域)
        Canvas canvas = new Canvas(bmp01);
        //先画出bmp01
        canvas.drawBitmap(bmp01, 0, 0, null);
        //再画出bmp02(bmp02,画在bmp01的中间)
        canvas.drawBitmap(bmp02, w1 / 2 - w2 / 2, h1 / 2 - h2 / 2, null);
        //保存
        canvas.save(Canvas.ALL_SAVE_FLAG);
        //恢复到原来的状态
        canvas.restore();

        return bmp01;
    }


    /**
     * 根据指定的内容和指定的宽和高生成二维码
     * @param str 生成二维码的信息
     * @param wAndH 二维码图片的宽和高
     * @return 生成的二维码图片
     */
    private Bitmap getQRCode(String str, int wAndH) {
        //构建生成二维码的对象
        MultiFormatWriter formatWriter = new MultiFormatWriter();
        Map<EncodeHintType, Object> map = new HashMap<>();
        //设置生成二维码的编码字符类型
        map.put(EncodeHintType.CHARACTER_SET, "UTF-8");
        try {
            //调用其中encode方法生成的位图矩阵BitMatrix
            /**
             * 参数1:生成二维码需要的字符串信息
             * 参数2:生成码的格式(条形码,一维码,二维码)
             * 参数3:生成位图矩阵的宽
             * 参数4:生成位图矩阵的高
             * 参数5:对生成二维码过程的一些配置Map
             */
            //把字符串信息转换成位图矩阵
            BitMatrix bitMatrix = formatWriter.encode(str, BarcodeFormat.QR_CODE, wAndH, wAndH, map);

            int[] p = new int[wAndH * wAndH];
            //把位图矩阵转化成一维数组(存储颜色信息)
            //外层控制行数
            for (int i = 0; i < wAndH; i++) {
                //j控制列数
                for (int j = 0; j < wAndH; j++) {
                    //说明在i行j列上有值
                    if (bitMatrix.get(i, j)) {
                        //表示有值
                        p[i * wAndH + j] = Color.BLACK;
                    } else {
                        //表示为空
                        p[i * wAndH + j] = Color.WHITE;
                    }

                }
            }

            //把颜色只变成像素点填充为图片Bitmap
            //先创建一个空的bitmap(宽和高,Config)
            Bitmap bmp = Bitmap.createBitmap(wAndH, wAndH, Bitmap.Config.ARGB_8888);

            //把颜色值当作像素点填到Bitmap
            /**
             * 参数1:把一维数组存储的值写入到Bitmap
             * 参数2:从一维数组中读取的第一个像素值的索引或者下标
             * 参数3:宽度
             * 参数4:写入图片的第一个像素点的x坐标
             * 参数5:写入图片的第一个像素点的y坐标
             * 参数6:宽度
             * 参数7:高度
             */
            bmp.setPixels(p, 0, wAndH, 0, 0, wAndH, wAndH);


            return bmp;
        } catch (WriterException e) {
            e.printStackTrace();
        }
        return null;

    }


    /**
     * 生成中心带有logo的二维码
     * @param text 需要生成二维码的内容
     * @param widthAndHeight 生成二维码图片的宽和高
     * @param mBitmap 中心logo 图片
     * @param imgWAndH 中心logo 图片的宽和高,这个值不能太大,否则不识别,一般建议小于20即可
     * @return 生成二维码的图片
     */
    public Bitmap generateQRCode(String text, int widthAndHeight, Bitmap mBitmap, int imgWAndH) {
        Matrix m = new Matrix();
        float sx = (float) 2 * imgWAndH / mBitmap.getWidth();
        float sy = (float) 2 * imgWAndH / mBitmap.getHeight();
        m.setScale(sx, sy);//设置缩放信息
        //将logo图片按martix设置的信息缩放
        mBitmap = Bitmap.createBitmap(mBitmap, 0, 0,
                mBitmap.getWidth(), mBitmap.getHeight(), m, true);
        //imageView.setBackgroundDrawable(new BitmapDrawable(mBitmap));
        Hashtable<EncodeHintType, Object> hashtable = new Hashtable<>();
        hashtable.put(EncodeHintType.CHARACTER_SET, "utf-8");
        hashtable.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);
        try {
            BitMatrix bitMatrix = new MultiFormatWriter()
                    .encode(editText_info.getText().toString(), BarcodeFormat.QR_CODE,
                            widthAndHeight, widthAndHeight);
            int[] pixles = new int[widthAndHeight * widthAndHeight];
            int halfW = widthAndHeight / 2;
            int halfH = widthAndHeight / 2;
            //控制行数
            for (int i = 0; i < widthAndHeight; i++) {
                //控制列数
                for (int j = 0; j < widthAndHeight; j++) {
                    if (i > halfW - imgWAndH && i < halfW + imgWAndH
                            && j > halfH - imgWAndH
                            && j < halfH + imgWAndH) {//该位置用于存放图片信息
                        //记录图片每个像素信息
                        pixles[i * widthAndHeight + j] = mBitmap.getPixel
                                (j - halfH + imgWAndH,
                                        i - halfW + imgWAndH);
                    } else {
                        if (bitMatrix.get(i, j)) {//如果有黑块点,记录信息
                            pixles[i * widthAndHeight + j] = Color.BLACK;//记录黑块信息
                        }
                    }
                }
            }
            Bitmap bmp1 = Bitmap.createBitmap(widthAndHeight, widthAndHeight, Bitmap.Config.ARGB_8888);
            bmp1.setPixels(pixles, 0, widthAndHeight, 0, 0, widthAndHeight, widthAndHeight);
            return bmp1;

        } catch (Exception e) {
            e.getMessage();
        }
        return null;
    }


    private void initView() {
        this.button_scanner= (Button) this.findViewById(R.id.button_scanner);
        this.editText_info= (EditText) this.findViewById(R.id.editText_info);
        this.button_generator= (Button) this.findViewById(R.id.button_generator);
        this.imageView_QuickResponseCode= (ImageView) this.findViewById(R.id.imageView_QuickResponseCode);
    }

    @Override
    protected void onActivityResult(int requestCode, int resultCode, Intent data) {
        if(requestCode==100){
            if(resultCode==RESULT_OK){
                if(data!=null){
                    String result=data.getStringExtra("result");
                    Toast.makeText(this, "扫描结果为:"+result, Toast.LENGTH_SHORT).show();
                    System.out.println("result="+result);
                }
            }
        }
    }
}

看看运行的效果:


当我们点击扫一扫解二维码时就可以打开手机的相机,

我们可以在本文框里输入内容,然后点击生成二维码,就可以将我们输入的内容变成二维码


这样就完成是二维码的基本操作了,你们可以用微信扫一下,是不是很简单!

评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

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

抵扣说明:

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

余额充值