一、二维码生成
思路:将字符串中的每个字符转为二进制码字符串,保存在二进制码字符串数组中。对二进制码字符串数组中的每个二进制码字符串进行字符遍历,若是‘0’,则设置画笔颜色为白色,若是‘1’,则设置画笔颜色为黑色。最后绘制图片。
例如,生成字符串"http://bilibili.com"的二维码
1、将字符串中的每个字符转为二进码字符串
String str="http://bilibili.com";
for(int i=0;i<str.length();i++) {
char c=str.charAt(i);//获取字符串中的每个字符
String binarystring=Integer.toBinaryString(c);//将字符转为而二进码字符串
此时我们打印输出二进码字符串,会发现输出的二进制数不规则,有7bit也有8bit的。所以我们需要对不足8bit的二进数前面补‘0’,使得到的二进数都是8bit的,然后再将其保存到数组中。
//补码 在二进制数不足8个bit的前面补0
while(binarystring.length()<8) {
binarystring=0+binarystring;
}
2、保存在二进制码字符串数组中
String[] Binarystring=new String[str.length()];//定义一个一维数组
for(int j=0;j<str.length();j++) {
Binarystring[i]=binarystring;
}
3、遍历二进制码字符串中的字符,设置画笔颜色,绘制图片
for(int i=0;i<binarystring.length;i++) {
String str=binarystring[i];
for(int j=0;j<str.length();j++) {
char c=str.charAt(j);
if(c=='0') {
g.setColor(Color.white);
}else {
g.setColor(Color.black);
}
g.fillRect(200+i*10, 100+j*10, 10, 10);
}
}
}
4、完整代码
QRcode类:将字符串转换为二进码字符串,创建保存二进码字符串数组
public class QRcode {
String str="http://bilibili.com";
String[] Binarystring=new String[str.length()];//定义一个一维数组
public String[] tobinarystring() {
for(int i=0;i<str.length();i++) {
char c=str.charAt(i);//获取字符串中的每个字符
String binarystring=Integer.toBinaryString(c);//字符转为二进制码字符串
//System.out.println(binarystring);//输出的二进制不规则 有7个bit也有8个bit
//补码 在二进制数不足8个bit的前面补0
while(binarystring.length()<8) {
binarystring=0+binarystring;
}
//此时二进制数都是8个bit 需将这些二进数存储到数组中
for(int j=0;j<str.length();j++) {
Binarystring[i]=binarystring;
}
}
return Binarystring;
}
}
QRcodeUI类:二维码窗体界面类,用来绘制二维码(二值化图片)
import java.awt.Color;
import java.awt.Graphics;
import javax.swing.JFrame;
public class QRcodeUI extends JFrame {
private static final long serialVersionUID = 1L;
QRcode qrcode=new QRcode();
String[] binarystring=qrcode.tobinarystring();//调用QRcode类中创建二进制码字符串数组的方法
//创建窗体界面
public void init() {
setTitle("二维码");
setSize(800,600);
setDefaultCloseOperation(EXIT_ON_CLOSE);
setVisible(true);
Graphics g=getGraphics();
paint(g);
}
//创建绘图方法
public void paint(Graphics g) {
super.paint(g);
//遍历二进制码字符串中的字符
for(int i=0;i<binarystring.length;i++) {
String str=binarystring[i];
for(int j=0;j<str.length();j++) {
char c=str.charAt(j);
//设置画笔颜色
if(c=='0') {
g.setColor(Color.white);
}else {
g.setColor(Color.black);
}
//绘制图片
g.fillRect(200+i*10, 100+j*10, 10, 10);
}
}
}
public static void main(String[]args) {
QRcodeUI qrdcodeui=new QRcodeUI();
qrdcodeui.init();
}
}
5、效果图
5
二、二维码识别
思路:将获得的二维码图片转为int类型的二维数组,保存该图片的像素点。根据图片的宽度和方向进行取值,并设置灰度值,若灰度值大于100,则取二进制码0,否则则取1,从而获得二进码字符串。将获得的二进制码字符串先转为整数,再强制转为字符。然后将获得的字符保存到字符数组中,最后遍历输出字符数组中的字符。
1、将二维码图片转为int类型的二维数组
public int[][] getpixelarray(String imgpath){
BufferedImage img=null;
try {
img=ImageIO.read(new File(imgpath));//根据路径生成图片
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//获取图片的宽和高
int w=img.getWidth();
int h=img.getHeight();
int[][] imgarr=new int[w][h];
for(int i=0;i<w;i++) {
for(int j=0;j<h;j++) {
imgarr[i][j]=img.getRGB(i, j);
}
}
return imgarr;
}
2、设置灰度值,根据灰度值进行判断,获得二进码字符串
int[][] imgarr= getpixelarray("C:\\Users\\011\\Pictures\\Saved Pictures\\QRcode1.png");
int w=imgarr.length;
int width=w/20;//格子宽度
//考虑到可能会取到边界,所以需要改变起点,i、j不是从0取起,从每个矩形中点取起
for(int i=width/2;i<imgarr.length;i+=width) {
String str="";//声明字符串
for(int j=width/2;j<width*8;j+=width) {//每隔一个格子来取rgb值
int rgb=imgarr[i][j];
Color color=new Color(rgb);
int gray=(color.getRed()+color.getBlue()+color.getGreen())/3;//引入灰度值来判断取0还是1
if(gray>150) {
str+="0";//格子颜色为黑色就取0
}else {
str+="1";
}
}
}
3、将获得的二进码字符串进行类型转换
int in=Integer.parseInt(str, 2);
char c=(char)+in;
4、将获得的字符保存到字符数组中,最后遍历输出字符数组中的字符
char[] ch=new char[20];//声明一个字符型数组,用来保存转换好的字符
int t=0;//数组下标
for(int i=width/2;i<imgarr.length;i+=width) {
String str="";//声明字符串
for(int j=width/2;j<width*8;j+=width) {//每隔一个格子来取rgb值
int rgb=imgarr[i][j];
Color color=new Color(rgb);
int gray=(color.getRed()+color.getBlue()+color.getGreen())/3;//引入灰度值来判断取0还是1
if(gray>150) {
str+="0";//格子颜色为黑色就取0
}else {
str+="1";
}
}
int in=Integer.parseInt(str, 2);
char c=(char)+in;
ch[t]=c;
t++;//每保存一个字符,下标下移
}
for(int k=0;k<ch.length;k++) {
System.out.print(ch[k]);//输出保存好的字符
}
5完整代码
import java.awt.Color;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
public class QRcodedefi {
//将二维码图片转为int类型的二维数组
public int[][] getpixelarray(String imgpath){
BufferedImage img=null;
try {
img=ImageIO.read(new File(imgpath));//根据路径生成图片
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
//获取图片的宽和高
int w=img.getWidth();
int h=img.getHeight();
int[][] imgarr=new int[w][h];
for(int i=0;i<w;i++) {
for(int j=0;j<h;j++) {
imgarr[i][j]=img.getRGB(i, j);
}
}
return imgarr;
}
//将获取的二维数组中保存的像素值转为二进制码
public void tobinary() {
int[][] imgarr= getpixelarray("C:\\Users\\011\\Pictures\\Saved Pictures\\QRcode1.png");
int w=imgarr.length;
int width=w/20;//格子宽度
char[] ch=new char[20];//声明一个字符型数组,用来保存转换好的字符(将得到的二进制码字符串先转为整数再转为字符)
int t=0;//数组下标
//考虑到可能会取到边界,所以需要改变起点,i、j不是从0取起,从每个矩形中点取起
for(int i=width/2;i<imgarr.length;i+=width) {
String str="";//声明字符串
for(int j=width/2;j<width*8;j+=width) {//每隔一个格子来取rgb值
int rgb=imgarr[i][j];
Color color=new Color(rgb);
int gray=(color.getRed()+color.getBlue()+color.getGreen())/3;//引入灰度值来判断取0还是1
if(gray>150) {
str+="0";//格子颜色为黑色就取0
}else {
str+="1";
}
}
int in=Integer.parseInt(str, 2);
char c=(char)+in;
ch[t]=c;
t++;//每保存一个字符,下标下移
System.out.println(str+"---"+(char)+in);
}
for(int k=0;k<ch.length;k++) {
System.out.print(ch[k]);//输出保存好的字符
}
}
public static void main(String[]args) {
QRcodedefi qrcodedefi=new QRcodedefi();
qrcodedefi.tobinary();
}
}
6、效果图