带你玩转二维码

zxing二维码位矩阵转换成Bitmap位图 阅读详情

  什么是二维码:

        二维条码/二维码(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);
                }
            }
        }
    }
}

看看运行的效果:


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

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


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

二维码Bitmap的直接识别 在继成二维码库中,我们可以使用以下代码来进行直接识别自己的二维码 MultiFormatReader multiFormatReader = new MultiFormatReader(); Hashtable<DecodeHintType, Object> hints = new Hashtable<DecodeHintType, Object>(2); Vector<BarcodeFormat> decodeForma 阅读详情

相关推荐

别再只会生成黑白二维码了!用Python qrcode库玩转彩色、圆角、带Logo的个性化二维码

本文详细介绍了如何使用Python qrcode库创建个性化二维码,包括渐变色彩、圆角设计和Logo嵌入等高级技巧。通过实战案例和代码示例,帮助开发者提升二维码的美观度和扫描率,适用于品牌营销和创意项目。

weixin_33139275的博客 263

二维码生成

1.添加依赖: implementation ‘cn.bingoogolapple:bga-qrcode-zxing:1.2.1’ 2.调用QRCodeEncoder.syncEncodeQRCode的方法并返回bitmap

qq_43589732的博客 213

【小程序demo】带你玩转支付宝小程序之小程序二维码

小程序二维码 小程序二维码能力可使得开发者更便捷地推广小程序,开发者可以将生成后的小程序二维码在线上线下进行贴码推广。 前提条件 已完成开发者入驻与小程序创建。 已下载并安装小程序开发者工具 获取模板代码 下载小程序二维码Demo.zip文件,并解压至本地。 使用步骤 添加功能 1.登录小程序开发中心,在我的小程序中,选择相应的小程序,进入该小程序详情页。 2.在小程...

m0_44944537的博客 2998

探索开源项目:`QRCode` - 简易二维码生成与解析库

探索开源项目:QRCode - 简易二维码生成与解析库 在这个信息化时代,二维码已经无处不在,无论是线上支付、网址跳转还是名片交换,都离不开它的身影。今天我们要介绍的是一款简洁高效的二维码处理库——,它为开发者提供了一种简单的方式来生成和解析二维码,让我们一起来看看这个项目的技术细节和应用场景。 项目简介 QRCode 是一个用 Java 开发的轻量级二维码生成器,其设计目标是易于使用且性能出色。...

gitblog_00067的博客 671

别再只会画黑白块了!用uQRCode在UniApp里玩转带Logo和边框的个性二维码

本文详细介绍了如何在UniApp中使用uQRCode生成带Logo和边框的个性化二维码,提升品牌视觉体验。通过实战案例和性能优化策略,帮助开发者掌握自定义绘制技巧,实现高效、美观的二维码设计。

weixin_33563728的博客 309

别再只会生成黑白码了!用uQRCode在UniApp里玩转彩色、带Logo和边框的个性化二维码

本文详细介绍了如何在UniApp中使用uQRCode插件创建彩色、带Logo和边框的个性化二维码。通过渐变色彩、Logo集成和动态边框等高级技巧,帮助开发者提升二维码的视觉吸引力,适用于营销活动、品牌展示等多种场景。

weixin_31309419的博客 322

玩转安卓带logo的二维码

好久没有写博客了,快元旦了公司的事情也不是很多,刚好和朋友一起出去玩玩,朋友是搞php的说到了每天在公司都是搞些什么二维码和微信支付的相关东西,因为上班的时间不忙,所以随便来搞下。 二维码(Quick Response Code),又称二维条码,它是用特定的几何图形按一定规律在平面(二维方向)上分布的黑白相间的图形,是所有信息数据的一把钥匙。在现代商业活动中,如果一个产品是不能通过二维码来进行访

Losileeya 1360

别再只会生成黑白码了!用uQRCode在UniApp里玩转带Logo和边框的个性二维码(附完整代码)

本文详细介绍了如何在UniApp中使用uQRCode库实现带Logo和边框的个性化二维码设计。通过高级定制技术,包括品牌Logo融合、动态边框设计和渐变色彩方案,开发者可以创建兼具功能性与视觉冲击力的二维码。文章提供了完整的代码示例和性能优化建议,帮助开发者轻松实现二维码的美学升级。

weixin_30582943的博客 242

别再只会生成黑白二维码了!用Python的qrcode库玩转彩色、圆角、带Logo的个性化二维码

本文详细介绍了如何使用Python的qrcode库创建高颜值二维码,包括渐变色彩、圆角设计、Logo嵌入和动态效果等进阶技巧。通过代码示例和实用建议,帮助开发者提升二维码的视觉吸引力和扫码率,适用于品牌营销和个人项目。

weixin_31992389的博客 312

二维码生成BitMap图片

二维码生成BitMap图片 创建二维码图片,转换

Laravel开发-simple-qrcode

Laravel开发-simple-qrcode 简单的QRcode是一个为Laravel制作的二维码生成器。

不只是扫一扫:用CTF题‘神奇二维码’带你玩转多媒体文件隐写术

本文通过CTF题目‘神奇二维码’深入探讨多媒体文件隐写术的应用与实践。从二维码的容错机制到图片、音频、压缩包等多种文件的隐写技术,详细解析了LSB隐写、频谱隐写等核心方法,并提供了Python代码示例和工具使用指南,帮助读者掌握信息安全领域的隐蔽信息传递技巧。

weixin_30736301的博客 328

二维码生成工具QRCode源代码支持中文(解决解码时中文乱码)

我是这个资源的上传者,这个资源是老版本资源了。 新版本同功能的资源在http://download.youkuaiyun.com/detail/5653325/5077697

03_互联网99%的二维码毫无新意,但Python...

这里写自定义目录标题二维码de前世今生MyQR 神器支持背景图的二维码支持动态图的二维码 二维码de前世今生 二维码又称二维条码,常见的二维码为QR Code,QR全称Quick Response ,是一个近几年来移动设备上超流行的一种编码方式,它比传统的Bar Code条形码能存更多的信息,也能表示更多的数据类型。 二维码是由日本的Denso Wave公司发明,但是国人才真正的把二维码发扬光...

lsqzedu的博客 290

HybridCLR热更新打包报错全解析:从原理到实战解决方案

热更新技术是现代游戏和应用开发中实现动态内容交付与Bug修复的核心机制,它允许开发者在无需重新发布完整应用的情况下更新代码逻辑。其原理通常涉及在运行时加载并执行新的代码模块,这要求框架在底层实现安全的代码隔离、内存管理与元数据桥接。在Unity生态中,HybridCLR作为基于IL2CPP的高性能热更新解决方案,通过补充元数据和AOT泛型引用技术,实现了对C#代码的原生级热更支持,显著提升了开发迭代效率与线上问题修复能力。然而,在实际的工程实践中,尤其是在面向Android、iOS等多平台打包构建时,开发者

weixin_29017445的博客 309

检索生成(RAG) vs 长文本大模型:实际应用中如何选择?

大模型的上下文理解能力直接影响到 LLMs 在复杂任务和长对话中的表现。本期内容聚焦于两种主流技术:长上下文(Large Context Windows)和检索增强生成(RAG)。这两种技术各有何优势?在实际应用中,我们又该如何权衡选择?文章不仅详细阐述了这两种技术的工作原理,还深入分析了它们在效率、准确性和实施成本等方面的差异。文章特别提到了在执行重复性任务时使用 Context Caching 优化长上下文的优势,然而,缓存策略的效果很大程度上取决于提示词的可预测性。

2401_85782938的博客 1255

别再只会画黑白块了!用uQRCode在UniApp里玩转带Logo和边框的个性二维码(附完整代码)

本文详细介绍了如何在UniApp中使用uQRCode库创建带Logo和边框的个性化二维码,提升品牌识别度。从技术原理到实战代码,涵盖Logo嵌入、边框设计、文字整合及性能优化等高级定制技巧,帮助开发者打造兼具美观与实用性的二维码解决方案。

weixin_30296405的博客 426

视觉Transformer实战 | Token-to-Token Vision Transformer(T2T-ViT)详解与实现

Vision Transformer (ViT) 在计算机视觉领域取得了巨大成功,但标准的 ViT 存在一些局限性,如需要大规模预训练数据、对局部结构建模不足等。Token-to-Token ViT (T2T-ViT) 通过引入渐进式分词过程改进了原始 ViT,使其能够在中小型数据集上取得更好的性能。本节将详细介绍 T2T-ViT 的技术原理,并使用 PyTorch 从零开始实现 T2T-ViT。

盼小辉丶的博客 4万+

别再只会生成黑白块了!用uQRCode在uniapp里玩转带Logo和边框的个性二维码(附完整代码)

本文详细介绍了如何在uniapp中使用uQRCode实现带Logo和边框的个性化二维码生成。通过环境配置、动态边框建模、LOGO融合、动态标题排版等五个维度,帮助开发者突破传统黑白二维码的限制,提升用户扫码率。附完整代码和性能优化建议,适用于电商、数字名片等多种场景。

weixin_29611239的博客 371

SolidWorks速成教程P3-5【零件 | 第五节】——异形孔向导&线性阵列&镜像

这节介绍异形孔向导、线性阵列、镜像。

嵌入式阿齐Archie 6073

基于simulink的BMS系统中电池单体故障隔离与恢复建模

本文介绍了使用Simulink构建BMS电池单体故障诊断与容错控制模型的方法。主要内容包括:1)搭建12串锂电池组模型;2)实现单体故障注入(过压、断线等);3)设计故障诊断与隔离模块(采用Stateflow状态机);4)开发恢复判断逻辑(需满足电压、温度等条件);5)系统监控与仿真设置。文章还提供了工程实践建议,如防环流设计、通信冗余等,并指出进阶方向(多故障处理、AI预警等)。该模型适用于新能源汽车、储能系统的BMS设计,可提高系统可靠性和安全性。

xiaoheshang_123的博客 140

摸鱼八年,我用 Java 把二维码玩出花

二维码已经彻底渗透到我们生活的每个角落。作为一名干了八年 Java 的程序员(主要在摸鱼,但也干活),我最近接到一个需求:

hehehaha2025的博客 86

华为OD机试双机位C卷-MVP争夺战 (C/C++/Py/Java/Js/Go)

华为OD机试(机考)双机位C卷 【MVP争夺战】,提供C语言、Java、C++、Python、Go、JavaScript源码实现,并提供完整思路讲解,以及在线OJ模拟做题。华为OD机试 - MVP争夺战,

qq_45776114的博客 1170
上一篇: picasso-强大的Android图片下载缓存库
下一篇: 第三方登录
小小小桂丶
博客等级 码龄10年 1粉丝 7原创
评论
成就一亿技术人!
拼手气红包6.0元
还能输入1000个字符
 
 条评论被折叠 查看
添加红包

请填写红包祝福语或标题

个

红包个数最小为10个

元

红包金额最低5元

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

抵扣说明:

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

余额充值