精华内容
下载资源
问答
  • 图片识别二维码,同一信息多次生成二维码,生成的二维码的构造一样的吗? 近十年来,我国电子信息技术飞速发展,在这个通信技术高速发展的时代,产生的众多产品对我们的生活产生了重大的影响,它们让我们的生活变...

    图片识别二维码,同一信息多次生成二维码,生成的二维码的构造是一样的吗?

    近十年来,我国电子信息技术飞速发展,在这个通信技术高速发展的时代,产生的众多产品对我们的生活产生了重大的影响,它们让我们的生活变得便利,其中尤以二维码为我们的生活提供了巨大的便利,如网址链接二维码, 电子名片二维码, 文件生成二维码(图片,pdf,音频,视频), 文本二维码, 收款码二维码, 微信群二维码等等。
    二维码大都长得相似,那么他们是否一样呢?是不是同一信息多次生成的二维码构造都是一样的呢?

    二维码又称QR Code,QR全称Quick Response,是一个近几年来移动设备上超流行的一种编码方式,它能比传统的Bar Code条形码存更多的信息,也能表示更多的数据类型,比如:字符,数字,日文,中文等等。二维码一共有40个尺寸,官方叫版本Version。简单来说,二维码组合方式多,生成的信息容量大不会影响使用。每个二维码承载的信息都是独特的,所以不用担心二维码重复的情况。

    首先我们需要了解一下二维码的生成构图原理:二维码是用平面上分布的特定几何图形来记录信息的,在代码编制上巧妙的利用构成计算机内部逻辑基础的“0”、“1”比特流的概念,使用若干个与二进制相对应的几何形体来表示文字数值信息,通过图像输入设备或光电扫描设备自动识读以实现信息自动处理,它具有条码技术的一些共性,每种码制有其特定的字符集,每个字符占有一定的宽度、具有一定的校验功能等。
    由此可见,尽管二维码大多长得相似,但并不完全相同,不同的信息是被存储到不同的二维码当中的。
    想要了解关于二维码的更多信息,请进入二维彩虹试用。

    那么相同的内容多次生成二维码,是否那些二维码都是一样的呢?答案是否定的,二维码的生成是有一定算法的,而其中的一些算法会利用到随机数,会使图形格尽量均匀,即便是同样的内容,每次生成的二维码图案也都不一样。
    这是由于这些特定的几何图形都是按照一定规律,然后随机分布在平面上。就像我们写一个句子,不论是从左到右写,或者从上到下写,表达的都是同一个意思,但是它呈现的方式却不一样。

    所以,为了同一信息而生成多个二维码是不必要的,如果需要多个二维码链接,可以选择批量生成二维码,为其匹配不同的信息,既简便了使用者的操作,也能提高二维码的资源利用率。


    展开全文
  • Atitit java 二维码识别 图片识别   1.1. 解码11.2. 首先,我们先说一下二维码一共有40个尺寸。官方叫版本Version。11.3. 二维码的样例:21.4. 定位图案21.5. 数据编码31.6. 错误修正容量L水平7%的字码可被修正M...

    Atitit java 二维码识别 图片识别

     



    1.1. 解码1
    1.2. 首先,我们先说一下二维码一共有40个尺寸。官方叫版本Version。1
    1.3. 二维码的样例:2
    1.4. 定位图案2
    1.5. 数据编码3
    1.6. 错误修正容量L水平7%的字码可被修正M水平15%的字码可被修正Q水平25%的字码可被修正H水平30%的字码可被修正3
    1.7. QR是怎么对数据码加上纠错码的?3
    1.8. 画二维码图4
    1.9. 简要的编码过程:数据分析:确定编码的字符类型,按相应的字符集转换成符号字符; 选择纠错等级,7
    1.10. qr长度容量7




    1.1.解码
    编码lib:Qrcode_swetake.jar   (官网介绍-- http://www.swetake.com/qr/index-e.html)             
    解码lib:qrcode.jar                 (官网介绍-- http://sourceforge.jp/projects/qrcode/)




    1.2.首先,我们先说一下二维码一共有40个尺寸。官方叫版本Version。
    Version 1是21 x 21的矩阵,Version 2是 25 x 25的矩阵,Version 3是29的尺寸,每增加一个version,就会增加4的尺寸,公式是:(V-1)*4 + 21(V是版本号) 最高Version 40,(40-1)*4+21 = 177,所以最高是177 x 177 的正方形。




        /**
         * @param args the command line arguments
         */ 
        public static void main(String[] args) { 
            QRCodeDecoderHandler handler = new QRCodeDecoderHandler(); 
            String imgPath = "c:\\3bf33a87e950352a5936aa0a5543fbf2b2118b59.jpg"; 
            String decoderContent = handler.decoderQRCode(imgPath,"gbk"); 
            System.out.println("解析结果如下:"); 
            System.out.println(decoderContent); 
            System.out.println("========decoder success  !!!"); 
        } 
    1.3. 二维码的样例:




     
    1.4.定位图案
    Position Detection Pattern是定位图案,用于标记二维码的矩形大小。这三个定位图案有白边叫Separators for Postion Detection Patterns。之所以三个而不是四个意思就是三个就可以标识一个矩形了。
    Timing Patterns也是用于定位的。原因是二维码有40种尺寸,尺寸过大了后需要有根标准线,不然扫描的时候可能会扫歪了。
    Alignment Patterns 只有Version 2以上(包括Version2)的二维码需要这个东东,同样是为了定位用的。


    功能性数据
    Format Information 存在于所有的尺寸中,用于存放一些格式化数据的。
    Version Information 在 >= Version 7以上,需要预留两块3 x 6的区域存放一些版本信息。
    数据码和纠错码
    除了上述的那些地方,剩下的地方存放 Data Code 数据码 和 Error Correction Code 纠错码。
    1.5.数据编码
    我们先来说说数据编码。QR码支持如下的编码:数字,字符,byte


    1.6.错误修正容量L水平7%的字码可被修正M水平15%的字码可被修正Q水平25%的字码可被修正H水平30%的字码可被修正


    1.7.QR是怎么对数据码加上纠错码的?
    首先,我们需要对数据码进行分组,也就是分成不同的Block,然后对各个Block进行纠错编码,对于如何分组,我们可以查看QR Code Spec的第33页到44页的Table-13到Table-22的定义表。注意最后两列:




    1.8.画二维码图
    Position Detection Pattern
    首先,先把Position Detection图案画在三个角上。


    1.8.1.1.1.Alignment Pattern
    然后,再把Alignment图案画上


    关于Ali
    1.8.1.1.2.Timing Pattern
    接下来是Timing Pattern的线(这个不用多说了)


    1.8.1.1.3.Format Information
    再接下来是Formation Information,下图中的蓝色部分。


    Format Information是一个15个bits的信息,每一个bit的位置如下图所示:(注意图中的Dark Module,那是永远出现的)


    这15个bits中包括:
    5个数据bits:其中,2个bits用于表示使用什么样的Error Correction Level, 3个bits表示使用什么样的Mask
    10个纠错bits。主要通过BCH Code来计算
    然后15个bits还要与101010000010010做XOR操作。这样就保证不会因为我们选用了00的纠错级别,以及000的Mask,从重造
    1.8.1.1.4.Version Information
    再接下来是Version Information(版本7以后需要这个编码),下图中的蓝色部分。


    Version Information一共是18个bits,其中包括6个bits的版本号以及12个bits的纠错码,下面是一个示例:
    数据和数据纠错码
    然后是填接我们的最终编码,最终编码的填充方式如下:从左下角开始沿着红线填我们的各个bits,1是黑色,0是白色。如果遇到了上面的非数据区,则绕开或跳过。


    掩码图案
    这样下来,我们的图就填好了,但是,也许那些点并不均衡,所以,我们还要做Masking操作(靠,还嫌不复杂)QR的Spec中说了,QR有8个 Mask你可以使用,如下所示:其中,各个mask的公式在各个图下面。所谓mask,说白了,就是和上面生成的图做XOR操作。Mask只会和数据区进 行XOR,不会影响功能区。




    1.9.简要的编码过程:数据分析:确定编码的字符类型,按相应的字符集转换成符号字符; 选择纠错等级,
    在规格一定的条件下,纠错等级越高其真实数据的容量越小。数据编码:将数据字符转换为位流,每8位一个码字,整体构成一个数据的码字序列。其实知道这个数据码字序列就知道了二维码的数据内容。
    数据可以按照一种模式进行编码,以便进行更高效的解码,例如:对数据:01234567编码(版本1-H),1)分组:012 345 672)转成二进制:012→0000001100               345→0101011001                 67 →10000113)转成序列:0000001100 0101011001 10000114)字符数 转成二进制:8→00000010005)加入模式指示符(上图数字)0001:0001 0000001000 0000001100 0101011001 1000011对于字母、中文、日文等只是分组的方式、模式等内容有所区别。基本方法是一致的
    1.10.qr长度容量
    Cn utf8 984 
    Byte 2953byte 
    Ch 4296   num 7089








    1.11.二维码的解析


    1、定位图形:首先寻找探测图形,就是二维码上的三个方块。这三个方块的作用就是不管在哪个方向扫描图形,都可以扫到,不信可以将手机翻转测试一下。在通过二维码上的定位图形和分隔符确定二维码信息的图像。定位图形确定二维码符号中模块的坐标,二维码中的模块都是固定的,包括校正图形,版本信息,数据和纠错码。分隔符呢,就是将探测图形与二维码信息图像分开。


    2、灰度化二维码信息像素:手机拍到的图像都是彩色的,所以拍摄到二维码也不列外,它也是彩色的,只不过除了黑白,其他颜色非常浅而已。灰度化是指通过颜色的深浅来识别二维码,就是说颜色深的按深灰处理,浅色的按浅灰处理,去掉其他颜色。


    3、去掉二维码信息像素的噪点:相机的传感器在把光线作为接收信号和输出过程产生的粗糙像素,这些粗糙的像素是照片中不应该出现的干扰因素。噪点就是指这些粗糙的像素。


    4、二值化二维码信息像素:二值化是说将图像上像素灰度值设置为0或者255,也就是变成只有黑白两种颜色。第一步已经灰度化变成只有深灰和浅灰两种颜色,现在二值化是将深灰变成黑色,浅灰变成白色。为什么变成黑白色呢。因为二维码图像其实是由二进制的0或者1组成,0代表白色,1代表黑色。二维码在二值化时会将二维码图像变成只有黑白色的条码,然后根据解析公式什么的(因为像素是0-255之间,要全部转变成0或者255,估计得经过一些计算,然后0就是0,255变为1)转化成二进制信息。


    5、二维码译码和纠错:将得到的二进制信息进行译码和纠错。得到的二进制信息是版本格式信息、数据和纠错码经过一定的编码方式生成的,所以译码是对版本格式信息,数据和纠错码进行解码和对比。纠错是和译码同时进行的,将数据进行纠错。






    Atitit.二维码功能的设计实践 attilax 总结 - attilaxAti - 博客园.html
    atitit.二维码生成总结java zxing - attilax的专栏 - 博客频道 - CSDN.NET.html
     
    Java实现二维码QRCode的编码和解码 - 记忆是夏天 - 博客频道 - CSDN.NET.html
    二维码的生成细节和原理 - 51CTO.COM.html
    二维码原理介绍_百度经验.html
    二维码的生成和解析原理 - kelindame的专栏 - 博客频道 - CSDN.NET.html
    二维码的工作原理_百度知道.html


    作者:: 绰号:老哇的爪子 ( 全名::Attilax Akbar Al Rapanui 阿提拉克斯 阿克巴 阿尔 拉帕努伊 ) 
    汉字名:艾提拉(艾龙),   EMAIL:1466519819@qq.com
    转载请注明来源: http://www.cnblogs.com/attilax/
    Atiend


    展开全文
  • 玩转Android之二维码生成与识别

    万次阅读 多人点赞 2016-05-26 15:29:22
    二维码,我们也称作QRCode,QR表示quick response即...二维码的使用我主要想分为两部分来给大家介绍,一部分就是二维码的生成,这里的知识点都很简单,还有一部分是二维码识别,这里稍微麻烦一些,不过细心来做其实

    二维码,我们也称作QRCode,QR表示quick response即快速响应,在很多App中我们都能见到二维码的身影,最常见的莫过于微信了。那么今天我们就来看看怎么样在我们自己的App中集成二维码的扫描与生成功能。OK,废话不多说,我们就开始做吧。

    二维码的使用我主要想分为两部分来给大家介绍,一部分就是二维码的生成,这里的知识点都很简单,还有一部分是二维码的识别,这里稍微麻烦一些,不过细心来做其实也很简单。二维码的开发使用我们大多都是使用Google提供的zxing这个类库,使用这个类库我们需要先下载核心jar包,下载地址,如果我们只想生成二维码那么这个就够了,但是如果我们还想做二维码的识别,那么我们需要在刚才的基础上继续添加GitHub上的开源项目,这个我们在后面再说。

    1.二维码的生成

    先来看一张效果图:


    1.1  准备工作

    如果我们只做二维码的生成,那么只需要添加核心jar包即可,如下:


    1.2  二维码生成

    OK,添加完jar包之后我们就可以开始写二维码生成代码了,二维码本身就是一张Bitmap图片,所以我们这里主要就是看怎么样来生成这张图片,我在主界面添加一个按钮和一个ImageView,当点击按钮时生成一张二维码图片显示在ImageView上。布局如下:

    <?xml version="1.0" encoding="utf-8"?>
    <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="org.mobiletrain.qrwriter.MainActivity">
    
        <Button
            android:layout_width="wrap_content"
            android:layout_height="wrap_content"
            android:onClick="generate"
            android:text="生成二维码"/>
    
        <ImageView
            android:id="@+id/iv"
            android:layout_width="256dp"
            android:layout_height="256dp"
            android:layout_centerInParent="true"/>
    </RelativeLayout>

    当我点击按钮时生成二维码图片,那我们就来看看生成二维码图片的核心代码:

        private Bitmap generateBitmap(String content,int width, int height) {
            QRCodeWriter qrCodeWriter = new QRCodeWriter();
            Map<EncodeHintType, String> hints = new HashMap<>();
            hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
            try {
                BitMatrix encode = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);
                int[] pixels = new int[width * height];
                for (int i = 0; i < height; i++) {
                    for (int j = 0; j < width; j++) {
                        if (encode.get(j, i)) {
                            pixels[i * width + j] = 0x00000000;
                        } else {
                            pixels[i * width + j] = 0xffffffff;
                        }
                    }
                }
                return Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.RGB_565);
            } catch (WriterException e) {
                e.printStackTrace();
            }
            return null;
        }

    首先这个方法接收三个参数,这三个参数分别表示生成二维码的文本内容(你要把哪一个文本用二维码图片表示出来),第二个和第三个参数分别表示生成的二维码图片的宽和高。在这里,我们首先要获得一个QRCodeWriter实例,该实例中有一个方法叫做encode,通过该方法对文本内容进行编码,该方法共有五个参数,第一个参数表示生成二维码的文本内容,第二个参数表示编码格式,第三个参数表示生成的二维码的宽度,第四个参数表示生成的二维码的高度,第五个参数可选,可以用来设置文本的编码,encode方法的返回值是一个BitMatrix,你可以把BitMatrix理解成一个二维数组,这个二维数组的每一个元素都表示一个像素点是否有数据。OK,接下来我们需要定义一个int数组用来存放Bitmap中所有像素点的颜色,可是我们又怎么知道每一个像素点是什么颜色呢?这个时候就需要我们遍历BitMatrix了,如果BitMatrix上的点表示 该点有数据,那么对应在Bitmap上的像素点就是黑色,否则就是白色。BitMatrix中的get方法的返回值为一个boolean类型,true表示该点有数据,false表示该点没有数据。通过两个嵌套的for循环将BitMatrix遍历一遍,然后给pixels数组都赋上值,OK,pixels数组有值之后,接下来调用Bitmap的createBitmap方法创建一个Bitmap出来就可以了,createBitmap方法共接收6个参数,第一个参数表示Bitmap中所有像素点的颜色,第二个参数表示像素点的偏移量,第三个参数表示Bitmap每行有多少个像素点,第四个参数表示生成的Bitmap的宽度,第五个参数表示生成的Bitmap的高度,第六个参数表示生成的Bitmap的色彩模式,因为二维码只有黑白两种颜色,所以我们可以不用考虑透明度,直接使用RGB_565即可。OK,这样的话我们就获取到了二维码的图片了,最后我们再来看看点击事件:

        public void generate(View view) {
            Bitmap qrBitmap = generateBitmap("http://www.csdn.net",400, 400);
            iv.setImageBitmap(qrBitmap);
        }

    效果图如下:


    1.3  给二维码中心添加Logo

    OK,如果你没有特殊的需求那么这样就OK了,但是我们见到的大多数二维码的正中心都有一个Logo,那么这个效果要怎么实现呢?这里就是图片绘制的内容了,我封装了一个方法专门来解决这个问题,代码如下:

        private Bitmap addLogo(Bitmap qrBitmap, Bitmap logoBitmap) {
            int qrBitmapWidth = qrBitmap.getWidth();
            int qrBitmapHeight = qrBitmap.getHeight();
            int logoBitmapWidth = logoBitmap.getWidth();
            int logoBitmapHeight = logoBitmap.getHeight();
            Bitmap blankBitmap = Bitmap.createBitmap(qrBitmapWidth, qrBitmapHeight, Bitmap.Config.ARGB_8888);
            Canvas canvas = new Canvas(blankBitmap);
            canvas.drawBitmap(qrBitmap, 0, 0, null);
            canvas.save(Canvas.ALL_SAVE_FLAG);
            float scaleSize = 1.0f;
            while ((logoBitmapWidth / scaleSize) > (qrBitmapWidth / 5) || (logoBitmapHeight / scaleSize) > (qrBitmapHeight / 5)) {
                scaleSize *= 2;
            }
            float sx = 1.0f / scaleSize;
            canvas.scale(sx, sx, qrBitmapWidth / 2, qrBitmapHeight / 2);
            canvas.drawBitmap(logoBitmap, (qrBitmapWidth - logoBitmapWidth) / 2, (qrBitmapHeight - logoBitmapHeight) / 2, null);
            canvas.restore();
            return blankBitmap;
        }

    addLogo这个方法接收两个参数,第一个参数就是我们在1.2节中生成的二维码的Bitmap图片,第二个参数就是我们的logo图片,在该方法中我先获取到两张Bitmap各自的宽高,然后创建一个新的空白的Bitmap,这个新的空白的Bitmap的宽高和二维码的宽高一致,然后创建一个Canvas对象,创建Canvas对象的时候将blankBitmap传入,这样我一会绘制的东西相当于都是绘制在了blankBitmap上了。canvas的drawBitmap方法接收四个参数,第一个是你要绘制的Bitmap对象,第二个和第三个是你要绘制的Bitmap的左上角的坐标,第四个参数是一个画笔,一般情况下我们给一个null就可以了,如果你要设置重复模式等等效果的时候可以不给null。我们使用drawBitmap方法先将原本的二维码图片绘制出来,绘制完成之后,调用canvas的save方法,将当前的绘制状态保存下来,然后对画布进行缩放,缩小画布之后我们来绘制Logo,一帮情况下logo的宽高为二维码原图宽高的1/5(中心logo图片不宜过大,否则会影响到二维码的识别),所以我们先通过一个while循环获得缩放比例,然后调用canvas的scale方法对画布进行缩放,前两个参数表示宽高的缩放比例,大于1表示放大,小于1表示缩小,后两个参数表示缩放的中心点。缩放完成之后我们就可以绘制logo了,logo绘制完成之后,调用canvas的restore方法将画布恢复为原来的状态,最后将blankBitmap返回。在点击事件中调用这个方法即可,代码如下:

        public void generate(View view) {
            Bitmap qrBitmap = generateBitmap("http://www.csdn.net",400, 400);
            Bitmap logoBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);
            Bitmap bitmap = addLogo(qrBitmap, logoBitmap);
            iv.setImageBitmap(bitmap);
        }

    效果图如下:

    OK,至此,我们的二维码生成就说完了,就是这么简单。

    2.二维码的识别

    二维码的识别是一个稍微麻烦的事情,一般情况下,我们直接使用GitHub上的开源项目zxing即可,这个项目就是在我们之前的那个核心包的基础上完成的(下载地址)。当然,如果你需要自己定义相关的页面等等也都可以,这个我们到后面再说。这里我们先来看看怎么把GitHub上的开源项目引入到我们的项目中来。

    导入工程我们主要分为如下几个步骤:

    1.创建一个新的Project,命名为QRReader(这一步不是必须的,可以根据你的项目需求来)

    2.下载ZXing项目

    3.在新的Project中创建一个新的Module,在创建的过程中选择Android Library,如下图:

    4.在文件夹中打开我们的项目,找到第三步创建的Library,将第二步下载的ZXing项目中的android和android-core两个文件夹合并到library中,如下图:


    其中android文件夹中主要合并如下几个项目文件:

    合并完成之后再将我们之前下载的核心jar包夜拷贝到我们library的libs文件夹中,然后我们再来看看我们的library:

    5.在我们的项目中引用这个module,然后对项目进行编译。

    6.编译之后项目会报错,这个时候需要我们将library中所有的switch语句改为if...else if ...else if的形式。

    7.完成第6步之后还是会报错,这个时候需要我们将library的清单文件中Application节点的icon属性删除,再编译就没有任何问题了。

    OK,经过上面7个步骤这个开源项目就被我们成功的引入到我们自己的项目中了,在这个开源项目中有一个CaptureActivity,这个Activity专门用来扫描二维码,所以我们只需要在自己的项目中直接来启动这个Activity就可以了,另外,由于默认情况下CaptureActivity是启动项,所以我们要在library的清单文件中删除CaptureActivity作为启动项的配置。

    OK,现在我的项目中有一个按钮,点击这个按钮我就可以扫描二维码,代码如下:

        public void go(View view) {
            startActivity(new Intent(this, CaptureActivity.class));
        }

    OK,至此,一个简陋的二维码扫描就完成了,大家有木有觉得很麻烦啊?麻烦也就这一次,因为我把ZXing当作library使用的时候系统会自动生成一个aar包,有了这个aar包,以后的开发就会变得非常简单了,那么这个aar包在哪里呢?如下图:

    对应的文件夹路径大家自己去找,有了这个aar包之后,如果我再需要使用二维码扫描功能的时候就只需要如下几个简单的步骤:

    1.创建项目

    2.创建Module,在创建Module时选择Import .JAR/.AAR Package,然后选择刚刚的aar包

    3.在我的app中引用这个Module即可。



    最后,我将我自己生成的aar包提供给大家,可以直接在项目中使用,非常方便,不过建议还是大家自己尝试生成一个aar包,整个过程还是非常有意思。


    zxinglibrary-release.aar下载


    以上。


    展开全文
  • android二维码生成与识别

    千次阅读 2016-12-04 09:38:27
    二维码,我们也称作QRCode,QR表示quick response即快速...二维码的使用我主要想分为两部分来给大家介绍,一部分就是二维码的生成,这里的知识点都很简单,还有一部分是二维码识别,这里稍微麻烦一些,不过细心来做

    二维码,我们也称作QRCode,QR表示quick response即快速响应,在很多App中我们都能见到二维码的身影,最常见的莫过于微信了。那么今天我们就来看看怎么样在我们自己的App中集成二维码的扫描与生成功能。OK,废话不多说,我们就开始做吧。

    二维码的使用我主要想分为两部分来给大家介绍,一部分就是二维码的生成,这里的知识点都很简单,还有一部分是二维码的识别,这里稍微麻烦一些,不过细心来做其实也很简单。二维码的开发使用我们大多都是使用Google提供的zxing这个类库,使用这个类库我们需要先下载核心jar包,下载地址,如果我们只想生成二维码那么这个就够了,但是如果我们还想做二维码的识别,那么我们需要在刚才的基础上继续添加GitHub上的开源项目,这个我们在后面再说。

    1.二维码的生成

    先来看一张效果图:


    1.1  准备工作

    如果我们只做二维码的生成,那么只需要添加核心jar包即可,如下:


    1.2  二维码生成

    OK,添加完jar包之后我们就可以开始写二维码生成代码了,二维码本身就是一张Bitmap图片,所以我们这里主要就是看怎么样来生成这张图片,我在主界面添加一个按钮和一个ImageView,当点击按钮时生成一张二维码图片显示在ImageView上。布局如下:

    1. <?xml version="1.0" encoding="utf-8"?>  
    2. <RelativeLayout  
    3.     xmlns:android="http://schemas.android.com/apk/res/android"  
    4.     xmlns:tools="http://schemas.android.com/tools"  
    5.     android:layout_width="match_parent"  
    6.     android:layout_height="match_parent"  
    7.     tools:context="org.mobiletrain.qrwriter.MainActivity">  
    8.   
    9.     <Button  
    10.         android:layout_width="wrap_content"  
    11.         android:layout_height="wrap_content"  
    12.         android:onClick="generate"  
    13.         android:text="生成二维码"/>  
    14.   
    15.     <ImageView  
    16.         android:id="@+id/iv"  
    17.         android:layout_width="256dp"  
    18.         android:layout_height="256dp"  
    19.         android:layout_centerInParent="true"/>  
    20. </RelativeLayout>  

    当我点击按钮时生成二维码图片,那我们就来看看生成二维码图片的核心代码:
    1. private Bitmap generateBitmap(String content,int width, int height) {  
    2.     QRCodeWriter qrCodeWriter = new QRCodeWriter();  
    3.     Map<EncodeHintType, String> hints = new HashMap<>();  
    4.     hints.put(EncodeHintType.CHARACTER_SET, "utf-8");  
    5.     try {  
    6.         BitMatrix encode = qrCodeWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints);  
    7.         int[] pixels = new int[width * height];  
    8.         for (int i = 0; i < height; i++) {  
    9.             for (int j = 0; j < width; j++) {  
    10.                 if (encode.get(j, i)) {  
    11.                     pixels[i * width + j] = 0x00000000;  
    12.                 } else {  
    13.                     pixels[i * width + j] = 0xffffffff;  
    14.                 }  
    15.             }  
    16.         }  
    17.         return Bitmap.createBitmap(pixels, 0, width, width, height, Bitmap.Config.RGB_565);  
    18.     } catch (WriterException e) {  
    19.         e.printStackTrace();  
    20.     }  
    21.     return null;  
    22. }  

    首先这个方法接收三个参数,这三个参数分别表示生成二维码的文本内容(你要把哪一个文本用二维码图片表示出来),第二个和第三个参数分别表示生成的二维码图片的宽和高。在这里,我们首先要获得一个QRCodeWriter实例,该实例中有一个方法叫做encode,通过该方法对文本内容进行编码,该方法共有五个参数,第一个参数表示生成二维码的文本内容,第二个参数表示编码格式,第三个参数表示生成的二维码的宽度,第四个参数表示生成的二维码的高度,第五个参数可选,可以用来设置文本的编码,encode方法的返回值是一个BitMatrix,你可以把BitMatrix理解成一个二维数组,这个二维数组的每一个元素都表示一个像素点是否有数据。OK,接下来我们需要定义一个int数组用来存放Bitmap中所有像素点的颜色,可是我们又怎么知道每一个像素点是什么颜色呢?这个时候就需要我们遍历BitMatrix了,如果BitMatrix上的点表示 该点有数据,那么对应在Bitmap上的像素点就是黑色,否则就是白色。BitMatrix中的get方法的返回值为一个boolean类型,true表示该点有数据,false表示该点没有数据。通过两个嵌套的for循环将BitMatrix遍历一遍,然后给pixels数组都赋上值,OK,pixels数组有值之后,接下来调用Bitmap的createBitmap方法创建一个Bitmap出来就可以了,createBitmap方法共接收6个参数,第一个参数表示Bitmap中所有像素点的颜色,第二个参数表示像素点的偏移量,第三个参数表示Bitmap每行有多少个像素点,第四个参数表示生成的Bitmap的宽度,第五个参数表示生成的Bitmap的高度,第六个参数表示生成的Bitmap的色彩模式,因为二维码只有黑白两种颜色,所以我们可以不用考虑透明度,直接使用RGB_565即可。OK,这样的话我们就获取到了二维码的图片了,最后我们再来看看点击事件:
    1. public void generate(View view) {  
    2.     Bitmap qrBitmap = generateBitmap("http://www.csdn.net",400400);  
    3.     iv.setImageBitmap(qrBitmap);  
    4. }  

    效果图如下:


    1.3  给二维码中心添加Logo

    OK,如果你没有特殊的需求那么这样就OK了,但是我们见到的大多数二维码的正中心都有一个Logo,那么这个效果要怎么实现呢?这里就是图片绘制的内容了,我封装了一个方法专门来解决这个问题,代码如下:

    1. private Bitmap addLogo(Bitmap qrBitmap, Bitmap logoBitmap) {  
    2.     int qrBitmapWidth = qrBitmap.getWidth();  
    3.     int qrBitmapHeight = qrBitmap.getHeight();  
    4.     int logoBitmapWidth = logoBitmap.getWidth();  
    5.     int logoBitmapHeight = logoBitmap.getHeight();  
    6.     Bitmap blankBitmap = Bitmap.createBitmap(qrBitmapWidth, qrBitmapHeight, Bitmap.Config.ARGB_8888);  
    7.     Canvas canvas = new Canvas(blankBitmap);  
    8.     canvas.drawBitmap(qrBitmap, 00null);  
    9.     canvas.save(Canvas.ALL_SAVE_FLAG);  
    10.     float scaleSize = 1.0f;  
    11.     while ((logoBitmapWidth / scaleSize) > (qrBitmapWidth / 5) || (logoBitmapHeight / scaleSize) > (qrBitmapHeight / 5)) {  
    12.         scaleSize *= 2;  
    13.     }  
    14.     float sx = 1.0f / scaleSize;  
    15.     canvas.scale(sx, sx, qrBitmapWidth / 2, qrBitmapHeight / 2);  
    16.     canvas.drawBitmap(logoBitmap, (qrBitmapWidth - logoBitmapWidth) / 2, (qrBitmapHeight - logoBitmapHeight) / 2null);  
    17.     canvas.restore();  
    18.     return blankBitmap;  
    19. }  

    addLogo这个方法接收两个参数,第一个参数就是我们在1.2节中生成的二维码的Bitmap图片,第二个参数就是我们的logo图片,在该方法中我先获取到两张Bitmap各自的宽高,然后创建一个新的空白的Bitmap,这个新的空白的Bitmap的宽高和二维码的宽高一致,然后创建一个Canvas对象,创建Canvas对象的时候将blankBitmap传入,这样我一会绘制的东西相当于都是绘制在了blankBitmap上了。canvas的drawBitmap方法接收四个参数,第一个是你要绘制的Bitmap对象,第二个和第三个是你要绘制的Bitmap的左上角的坐标,第四个参数是一个画笔,一般情况下我们给一个null就可以了,如果你要设置重复模式等等效果的时候可以不给null。我们使用drawBitmap方法先将原本的二维码图片绘制出来,绘制完成之后,调用canvas的save方法,将当前的绘制状态保存下来,然后对画布进行缩放,缩小画布之后我们来绘制Logo,一帮情况下logo的宽高为二维码原图宽高的1/5(中心logo图片不宜过大,否则会影响到二维码的识别),所以我们先通过一个while循环获得缩放比例,然后调用canvas的scale方法对画布进行缩放,前两个参数表示宽高的缩放比例,大于1表示放大,小于1表示缩小,后两个参数表示缩放的中心点。缩放完成之后我们就可以绘制logo了,logo绘制完成之后,调用canvas的restore方法将画布恢复为原来的状态,最后将blankBitmap返回。在点击事件中调用这个方法即可,代码如下:
    1. public void generate(View view) {  
    2.     Bitmap qrBitmap = generateBitmap("http://www.csdn.net",400400);  
    3.     Bitmap logoBitmap = BitmapFactory.decodeResource(getResources(), R.mipmap.ic_launcher);  
    4.     Bitmap bitmap = addLogo(qrBitmap, logoBitmap);  
    5.     iv.setImageBitmap(bitmap);  
    6. }  

    效果图如下:

    OK,至此,我们的二维码生成就说完了,就是这么简单。

    2.二维码的识别

    二维码的识别是一个稍微麻烦的事情,一般情况下,我们直接使用GitHub上的开源项目zxing即可,这个项目就是在我们之前的那个核心包的基础上完成的(下载地址)。当然,如果你需要自己定义相关的页面等等也都可以,这个我们到后面再说。这里我们先来看看怎么把GitHub上的开源项目引入到我们的项目中来。

    导入工程我们主要分为如下几个步骤:

    1.创建一个新的Project,命名为QRReader(这一步不是必须的,可以根据你的项目需求来)

    2.下载ZXing项目

    3.在新的Project中创建一个新的Module,在创建的过程中选择Android Library,如下图:

    4.在文件夹中打开我们的项目,找到第三步创建的Library,将第二步下载的ZXing项目中的android和android-core两个文件夹合并到library中,如下图:


    其中android文件夹中主要合并如下几个项目文件:

    合并完成之后再将我们之前下载的核心jar包夜拷贝到我们library的libs文件夹中,然后我们再来看看我们的library:

    5.在我们的项目中引用这个module,然后对项目进行编译。

    6.编译之后项目会报错,这个时候需要我们将library中所有的switch语句改为if...else if ...else if的形式。

    7.完成第6步之后还是会报错,这个时候需要我们将library的清单文件中Application节点的icon属性删除,再编译就没有任何问题了。

    OK,经过上面7个步骤这个开源项目就被我们成功的引入到我们自己的项目中了,在这个开源项目中有一个CaptureActivity,这个Activity专门用来扫描二维码,所以我们只需要在自己的项目中直接来启动这个Activity就可以了,另外,由于默认情况下CaptureActivity是启动项,所以我们要在library的清单文件中删除CaptureActivity作为启动项的配置。

    OK,现在我的项目中有一个按钮,点击这个按钮我就可以扫描二维码,代码如下:

    1. public void go(View view) {  
    2.     startActivity(new Intent(this, CaptureActivity.class));  
    3. }  

    OK,至此,一个简陋的二维码扫描就完成了,大家有木有觉得很麻烦啊?麻烦也就这一次,因为我把ZXing当作library使用的时候系统会自动生成一个aar包,有了这个aar包,以后的开发就会变得非常简单了,那么这个aar包在哪里呢?如下图:

    对应的文件夹路径大家自己去找,有了这个aar包之后,如果我再需要使用二维码扫描功能的时候就只需要如下几个简单的步骤:

    1.创建项目

    2.创建Module,在创建Module时选择Import .JAR/.AAR Package,然后选择刚刚的aar包

    3.在我的app中引用这个Module即可。

    展开全文
  • 二维码,我们也称作QRCode,QR表示quick response即快速...二维码的使用我主要想分为两部分来给大家介绍,一部分就是二维码的生成,这里的知识点都很简单,还有一部分是二维码识别,这里稍微麻烦一些,不过细心来做
  • 我们通常只需要使用在线二维码生成器就可以制作二维码,但你知道它是怎么制作的吗?具体来讲,它所使用的技术就是计算机图像处理技术,在线二维码生成器的工作就是将所需的信息输入,生成相应的二维码,然后进行保存...
  • 怎么让IOS用户扫描二维码下载IOS版本,Android用户扫描二维码下载到Android版本呢? 实现思路: 首先,需要新建一个html文件,通过JavaScript来判断用户的手机系统(IOS或Android),判断之后,根据不同的手机...
  • 我返回的二维码怎么按都不弹出保存图片、识别二维码这些菜单,最多弹出个放大镜.... ``` <!-- 名片二维码" src=""> --> ``` 不知道这些样式要怎么设置,或者还是有别的标签? 到底怎样才能识别呢?
  • 二维码,我们也称作QRCode,QR表示quick response即快速...二维码的使用我主要想分为两部分来给大家介绍,一部分就是二维码的生成,这里的知识点都很简单,还有一部分是二维码识别,这里稍微麻烦一些,不过细心来做
  • 我们通常只需要使用在线二维码生成器就可以制作二维码,但你知道它是怎么制作的吗?具体来讲,它所使用的技术就是计算机图像处理技术,在线二维码生成器的工作就是将所需的信息输入,生成相应的二维码,然后进行保存...
  • 我在使用百度的文字识别时,需要拍摄照片,之后点击确认才能开始识别,请问如何可以像扫描二维码那样,在镜头中获得到需要的信息后自动拍摄。 谢谢解答
  • 二维码识别zbar.zip

    2020-04-12 13:21:57
    然后又继续优化了一下,发现二值化的阈值对二维码识别非常关键,badcase通常因为阈值不合适导致的,于是牺牲了一下性能,在识别程序中多次尝试不同阈值,最终识别效果达到了比较令人满意的结果,准确率从90%左右...
  • 用于扫描条形码或二维码的模块被统称为二维码扫描模块,在我们生活中的应用尤其多,比如自助购物机的扫码收款、超市自助收银设备、电影取票设备都有它的存在,那么二维码扫描模块是怎么分类的呢?下面远景达小编就给...
  • 二维码是什么?说起来并不复杂,任何信息都可以通过特定的编码算法转化为二维码,我们常见的一段复杂信息(比如一个很长的URL、一些加密后的字符串、或者一个复杂的快递编号)如果人工输入是非常繁琐并且误差很大的...
  • 51单片机二维码识别

    千次阅读 2019-07-23 10:05:39
    现在在做一个硬件项目,主要用“高端的”51单片机连一个摄像头完成二维码识别的问题。 目录: 一、解决方案 二、详细分析 一、解决方案: 现在的需求:给出二维码(可能存在图像偏移、旋转等问题),输出...
  • 分享一下华为的二维码\条形码识别(Android) 效果的的话,如下视频 华为的scan二维码和条形码扫描 这demo的效果,但是我们要的导入自己的的项目,并且获得自己想要的结果。 先看怎么导入吧 ...
  • 前言:有的时候需要进行二维码扫描,但是二维码是怎么在Unity中进行生成呢?本文将介绍到,同时还会涉及到另外一个插件,可以进行对二维码的扫描。   准备资料: ZXing.Net.0.14.0.0.zip 作用:实现
  • 二维码识别和生成二维码 前言:有的时候需要进行二维码扫描,但是二维码是怎么在Unity中进行生成呢?本文将介绍到,同时还会涉及到另外一个插件,可以进行对二维码的扫描。 准备资料:ZXing.Net.0.14.0.0.zip 作用...
  • python的pyzbar二维码识别时,中文全乱码 ...识别的结果中文部分全乱码: "³µÅÆ:¸ÓM31852,³µ¼ÜºÅ:LFV2A1156C3533424,¼ì²â½á¹û£ºÍ¨¹ý,±¨¸æ±àºÅ:360122012
  • c#在识别二维码这一块资源比较少,什么zxing那些用起来效果也不怎么好,所以这套代码楼主还是下了一番功夫才找到并整理的,代码主要用来识别二维码的,然后之前试过阿里,腾讯,百度的二维码识别,准确率都不高,...
  • 缘起需要检测发票中二维码的位置,以确定图像该怎么旋转,同时也可以为提取二维码信息创造先觉条件!(万恶的需求!)失败的尝试--opencv训练大法不感兴趣的可跳过不看!解释:原文作者训练检测舌头。。(蜜汁尴尬...
  • 在生活中,我们已经离不开二维码,无论是购物支付,信息展示,APP下载,停车缴费等都大量使用到二维码,并且在这一次疫情防控中,健康...二维码是如何被识别的?二维码到底可以存储多少信息?目前每天要消耗掉上百亿...

空空如也

空空如也

1 2 3 4 5 ... 12
收藏数 229
精华内容 91
关键字:

二维码是怎么识别的