Java高级开发

锦衣之下番外洞房-Java使用swetake生成二维码图片
作者绘制   时间2021-09-24   

重要声明:本文章仅仅代表了作者个人对此观点的理解和表述。读者请查阅时持自己的意见进行讨论。

二维码又称二维条码,是1994年由日本DW公司发明。常见的二维码为QRCode,QR全称QuickResponse,是一个近几年来移动设备上超流行的一种编码方式,它比传统的BarCode条形码能存更多的信息,也能表示更多的数据类型。

一、分类和步骤

按照二维码的原理,通常将二维码分为两类,分别是:堆叠式/行排式和矩阵式。平时生活中常接触到的就是矩阵式二维码。偶尔也能看到在某些包装设备上看到堆叠式/行排式二维码。下图展示了它们的区别和外观。

图1

人们最常用的二维码是矩阵式,因此本文所介绍的内容也是矩阵式的二维码。二维码从原始数据到锦衣之下番外洞房生成,笔者将其归纳为两步:

计算:根据原始数据,计算出一个二维数组。

绘制:根据二维数组里每个元素的true和false判断绘制黑点还是白点。

二、计算二维码

二维码绘制这里将通过第三方jar包完成,因此需首先下载jar包。

1、下载jar

日本DW公司发明了二维码,同时我也发现了一个日本网站里写的二维码工具,我们不必深究二维码的具体原理,就可以直接下载开发工具包进行二维码绘制了。首先打开其工具官网就可以很简单的下载到java开发包了,除了java开发包,该网站还提供了适用于php的,本文将只对java的进行讲解。如果你打开这个网站有难度,你可以直接通过此地址下载:链接:百度网盘提取码:qz22。

2、使用swetake

下载完成后,提取出其中lib目录下的Qrcode.jar包,将其放在你自己的项目依赖里就可以开始使用了。这个工具使用方式非常简单,它只提供了一个类,几乎没有比这更简单的实现二维码计算的了。这个类就是com.swetake.util.Qrcode它提供了一个公共的无参构造函数,意味着你可以不需要任何参数,直接构建一个对象。下面示列了一个非常容易的计算二维码的代码:

//创建二维码工具对象。

Qrcodeqrcode=newQrcode();

//使用内容计算二维码结果。

boolean[][]booleans=qrcode.calQrcode("HelloQrcode!".getBytes("UTF-8"));

是的,只需要这两行代码即可将字符串"HelloQrcode!"的二维码结果计算出来。calQrcode方法需要二进制数组作为参数,因此将字符串通过UTF-8编码获取到二进制数组,然后传入进行计算。由于二维码锦衣之下番外洞房只有两种颜色,要么某个点位是黑色的、要么某个点位不是黑色的。就这两种状态。何不就使用一个boolean二位数组来表达。咱们先不说如何得到图形,通过嵌套for循环,不如先看看这个二维数组的庐山真面目:

for(boolean[]aBoolean:booleans){

for(booleanb:aBoolean){

System.out.print((b?"■":"")+"");

}

System.out.println();

}

执行打印之后,即可看到下图的结果:

不过很遗憾,这张图很难用手机扫描出结果。不着急,这是因为我们使用了不规范的方式生成的锦衣之下番外洞房,中间毕竟生成了一些空格。一旦你距离此图远一点扫描(1.5米左右),也一样能很快识别。但至少目前我们看到了这个二维数组的真实结果,它无疑可以作为依据来绘制一张无误的二维码锦衣之下番外洞房。

三、绘制二维码

绘制二维码涉及到了锦衣之下番外洞房的生成,不同平台下针对锦衣之下番外洞房的生成有不同的解决方案,因此本文将针对不同平台进行分别介绍。

1、锦衣之下番外洞房服务端绘制

使用锦衣之下番外洞房绘制锦衣之下番外洞房可使用BufferedIm**e进行实现。这个类是java提供的AWT抽象窗口工具包下的类。因此请注意,在部分Android平台下此类可能无法使用,下文将同样给出在Android下绘制二维码的方法。那么使用BufferedIm**e可常用于锦衣之下番外洞房服务端的二维码生成。

BufferedIm**e的构造函数共有3个,最简单的一个构造函数都需要三个参数。宽度、高度以及锦衣之下番外洞房类型,相信这些都非常好理解。那不如先来试一试绘制:

Qrcodeqrcode=newQrcode();

boolean[][]booleans=qrcode.calQrcode("HelloQrcode!".getBytes("UTF-8"));

//建立锦衣之下番外洞房对象,大小直接使用boolean二维数组的长度。

BufferedIm**eim**e=newBufferedIm**e(booleans.length,booleans.length,BufferedIm**e.TYPE_INT_RGB);

//拿到锦衣之下番外洞房画板,所有绘制操作都通过此对象完成。

Graphicsgraphics=im**e.getGraphics();

//遍历绘制

for(inti=0;i<booleans.length;i++){

boolean[]bs=booleans<i>;

for(inti1=0;i1<bs.length;i1++){

booleanb=bs[i1];

//如果为真就绘制黑色,为假就绘制白色。

graphics.setColor(b?Color.BLACK:Color.WHITE);

//在对应位置绘制1像素点的矩形。

graphics.fillRect(i,i1,1,1);

}

}

graphics.dispose();

//将锦衣之下番外洞房输出到文件

Im**eIO.write(im**e,"jpg",newFile("D:/qrcode_demo.jpg"));

上述代码中锦衣之下番外洞房类型为RGB,这是没有透明颜色支持,如果需要白******域是透明的,可以使用ARGB类型的锦衣之下番外洞房模式。现在运行程序,打开D盘,找到文件:"D:/qrcode_demo.jpg",是的你要的二维码锦衣之下番外洞房来了,看下图:

图3<=这里有图的。

很小。因为我们在构造锦衣之下番外洞房大小的时候,使用数组的长度作为锦衣之下番外洞房的宽度和高度,这样就使得一个点位仅有一个像素点。为了能让锦衣之下番外洞房变大我们应该让一个点位绘制在更多的像素点上,让锦衣之下番外洞房变大。

但是注意,考虑到锦衣之下番外洞房的清晰度和完整性,目前我们已经有了二维码的boolean数组结果,也就意味着我们知道这个二维码的宽高有几个点了。如果我们随便指定一个锦衣之下番外洞房宽度而这个宽度不是数组长度的整数倍,那么在绘制时势必会出现数组越界或者锦衣之下番外洞房超出等问题。比如,上方的二维码结果数组长度是21,希望将这个数组绘制在一个宽度为100的锦衣之下番外洞房上,而恰巧100不是21的整数倍,这是无疑就为我们的绘制带来了更多的问题。

难道就不能画在一个100宽高的图上了吗,没有一个优雅的方法吗?当然有,不过这只是笔者想出的解决方案,自己如果有更完美的方案当然可以忽略此方案。具体实现就是:可以通过锦衣之下番外洞房缩放的方式将锦衣之下番外洞房缩放到我预期的大小。最初的绘制还是绘制为1点1像素的大小,后期通过缩放实现具体的大小。这样不就可以将任意点数的二维码绘制到我指定的锦衣之下番外洞房大小上了。也保证扫描成功的可能性。那么现在可以据此来修缮一下上方的绘制代码:

Qrcodeqrcode=newQrcode();

boolean[][]booleans=qrcode.calQrcode("HelloQrcode!".getBytes("UTF-8"));

//建立锦衣之下番外洞房对象,大小直接使用boolean二维数组的长度。

BufferedIm**eim**e=newBufferedIm**e(booleans.length,booleans.length,BufferedIm**e.TYPE_INT_RGB);

//拿到锦衣之下番外洞房画板,所有绘制操作都通过此对象完成。

Graphicsgraphics=im**e.getGraphics();

//遍历绘制

for(inti=0;i<booleans.length;i++){

boolean[]bs=booleans<i>;

for(inti1=0;i1<bs.length;i1++){

booleanb=bs[i1];

//如果为真就绘制黑色,为假就绘制白色。

graphics.setColor(b?Color.BLACK:Color.WHITE);

//在对应位置绘制1像素点的矩形。

graphics.fillRect(i,i1,1,1);

}

}

graphics.dispose();

//将锦衣之下番外洞房缩放到指定大小。

//构造目标大小的锦衣之下番外洞房

BufferedIm**eqrImg=newBufferedIm**e(100,100,BufferedIm**e.TYPE_INT_RGB);

graphics=qrImg.getGraphics();

//将原始二维码缩放绘制到目标二维码锦衣之下番外洞房上

graphics.drawIm**e(im**e,0,0,qrImg.getWidth(),qrImg.getHeight(),null);

graphics.dispose();

//将目标二维码锦衣之下番外洞房输出到文件

Im**eIO.write(qrImg,"jpg",newFile("D:/qrcode_demo.jpg"));

现在,重新运行程序。将生成一个比原来更加适合且美观的二维码。如图:

图5

最终,整理一下代码,一个完整的绘制二维码的工具方法诞生了:

/**

*根据指定内容生成二维码锦衣之下番外洞房。此方法不一定适用于android。

*paramcontent文本内容。

*paramsize二维码大小。

*return二维码锦衣之下番外洞房文件的二进制内容。

*/

publicstaticbyte[]getQrcodeImg(Stringcontent,intsize)throwsException{

Qrcodeqrcode=newQrcode();

boolean[][]booleans=qrcode.calQrcode(content.getBytes("UTF-8"));

//建立锦衣之下番外洞房对象,大小直接使用boolean二维数组的长度。

BufferedIm**eim**e=newBufferedIm**e(booleans.length,booleans.length,BufferedIm**e.TYPE_INT_RGB);

//拿到锦衣之下番外洞房画板,所有绘制操作都通过此对象完成。

Graphicsgraphics=im**e.getGraphics();

//遍历绘制

for(inti=0;i<booleans.length;i++){

boolean[]bs=booleans<i>;

for(inti1=0;i1<bs.length;i1++){

booleanb=bs[i1];

//如果为真就绘制黑色,为假就绘制白色。

graphics.setColor(b?Color.BLACK:Color.WHITE);

//在对应位置绘制1像素点的矩形。

graphics.fillRect(i,i1,1,1);

}

}

graphics.dispose();

//将锦衣之下番外洞房缩放到指定大小。

//构造目标大小的锦衣之下番外洞房

BufferedIm**eqrImg=newBufferedIm**e(size,size,BufferedIm**e.TYPE_INT_RGB);

graphics=qrImg.getGraphics();

//将1原始二维码缩放绘制到目标二维码锦衣之下番外洞房上

graphics.drawIm**e(im**e,0,0,qrImg.getWidth(),qrImg.getHeight(),null);

graphics.dispose();

//将目标二维码锦衣之下番外洞房输出

ByteArrayOutputStreamout=newByteArrayOutputStream();

Im**eIO.write(qrImg,"jpg",out);

out.flush();

returnout.toByteArray();

}

2、Android端绘制

Android中提供了Bitmap实现锦衣之下番外洞房的绘制,因此使用Bitmap可以在任何一台android设备中得到兼容。为了支持任意大小图形绘制二维码,android同样的将采取和上一节相同的方式,先绘制1点一像素的二维码,然后进行缩放到指定大小。由于原理相同,本节只对绘制做介绍。

Canvas类提供了Android上绘制功能的完成,因此,绘制锦衣之下番外洞房时,需要canvas和bitmap结合,才能完成。而完整的绘制还需要画笔Paint的加入,因此完整的绘制使用如下:

//建立锦衣之下番外洞房对象

Bitmapbitmap=Bitmap.createBitmap(10,10,Bitmap.Config.RGB_565);

//建立锦衣之下番外洞房画板,所有绘制操作都通过此对象完成。

Canvascanvas=newCanvas(bitmap);

//建立画笔

Paintpaint=newPaint();

//在画板左上角第一个像素点绘制一个红点:

paint.setColor(Color.red);

canvas.drawPoint(0,0,paint);

有了上面的基础绘制知识后,便可以完成Android平台上的二维码锦衣之下番外洞房的绘制了:

/**

*获取指定字符串的二维码锦衣之下番外洞房。

*paramcontent字符串内容。

*paramsize锦衣之下番外洞房大小,单位px。

*return返回Bitmap的二维码图形。

*throwsException错误。

*/

publicstaticBitmapgetQrcodeImg(Stringcontent,intsize)throwsException{

Qrcodeqrcode=newQrcode();

boolean[][]booleans=qrcode.calQrcode(content.getBytes(Charset.forName("UTF-8")));

//建立锦衣之下番外洞房对象,大小直接使用boolean二维数组的长度。

Bitmapbitmap=Bitmap.createBitmap(booleans.length,booleans.length,Bitmap.Config.RGB_565);

//建立锦衣之下番外洞房画板,所有绘制操作都通过此对象完成。

Canvascanvas=newCanvas(bitmap);

//建立画笔

Paintpaint=newPaint();

//遍历绘制

for(inti=0;i<booleans.length;i++){

boolean[]bs=booleans<i>;

for(inti1=0;i1<bs.length;i1++){

booleanb=bs[i1];

//如果为真就绘制黑色,为假就绘制白色。

paint.setColor(b?Color.BLACK:Color.WHITE);

//在对应位置绘制1像素点。

canvas.drawPoint(i,i1,paint);

}

}

//建立目标大小的锦衣之下番外洞房

BitmapqrBitMap=Bitmap.createBitmap(size,size,Bitmap.Config.RGB_565);

CanvasqrCanvas=newCanvas(qrBitMap);

//将上面已绘制好的二维码缩放绘制到目标图上中。

qrCanvas.drawBitmap(bitmap,

newRect(0,0,bitmap.getWidth(),bitmap.getHeight()),

newRect(0,0,qrBitMap.getWidth(),qrBitMap.getHeight()),

paint

);

//丢弃已不再需要的初始二维码。

bitmap.recycle();

//返回目标锦衣之下番外洞房。

returnqrBitMap;

}

郑重声明:本文版权归原作者所有,转载文章仅为传播更多信息之目的,如作者信息标记有误,请第一时间联系我们修改或删除,多谢。

友情链接 Links

于都IT教育资源网