由于最近需要做到条码又不想用什么jar包,并且查看jar包的api实在是太麻烦。所以就自己写了个条码工具类。
条码原理:主要是code128 其他类似。采用的是黑白相间的条纹组成。
每十一个单位的宽度的条纹 为一个单位,表示一个字符,这里除了结束符所有表示一个字符的条纹都是
由黑白黑白黑白 六条纹(只是宽度不同)组成,然后在对其相应条纹的宽度去查条码表,就会得到相应的字符。
code128,他分code128A、code128B、code128C,code128A基本上很少用,code128C表示纯数字并且是双数(01-99)
code128B表示数字、字母、符号。
Code128编码规则:开始位 + [FNC1(为EAN128码时加)] + 数据位 + 检验位 + 结束位 (我们这里不用就不加)
Code128检验位计算:(开始位对应的ID值 + 每位数据在整个数据中的位置×每位数据对应的ID值)% 103
编码表
例如:01234
StartC +01+23+CodeB+4+?+结束符 查询后为105+1+23+100+20+?+106
检验符=(1*105+2*1+3*23+4*100+5*20)% 103=58
最终编码为:105+1+23+100+20+58+106
package com;
import com.sun.deploy.util.StringUtils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
/**
* Created by 常发均 on 2020/5/12.
* 原创
*/
public class qrcodeUtil {
private int[][] CODE_PATTERNS = {
{2, 1, 2, 2, 2, 2}, // 0
{2, 2, 2, 1, 2, 2},
{2, 2, 2, 2, 2, 1},
{1, 2, 1, 2, 2, 3},
{1, 2, 1, 3, 2, 2},
{1, 3, 1, 2, 2, 2}, // 5
{1, 2, 2, 2, 1, 3},
{1, 2, 2, 3, 1, 2},
{1, 3, 2, 2, 1, 2},
{2, 2, 1, 2, 1, 3},
{2, 2, 1, 3, 1, 2}, // 10
{2, 3, 1, 2, 1, 2},
{1, 1, 2, 2, 3, 2},
{1, 2, 2, 1, 3, 2},
{1, 2, 2, 2, 3, 1},
{1, 1, 3, 2, 2, 2}, // 15
{1, 2, 3, 1, 2, 2},
{1, 2, 3, 2, 2, 1},
{2, 2, 3, 2, 1, 1},
{2, 2, 1, 1, 3, 2},
{2, 2, 1, 2, 3, 1}, // 20
{2, 1, 3, 2, 1, 2},
{2, 2, 3, 1, 1, 2},
{3, 1, 2, 1, 3, 1},
{3, 1, 1, 2, 2, 2},
{3, 2, 1, 1, 2, 2}, // 25
{3, 2, 1, 2, 2, 1},
{3, 1, 2, 2, 1, 2},
{3, 2, 2, 1, 1, 2},
{3, 2, 2, 2, 1, 1},
{2, 1, 2, 1, 2, 3}, // 30
{2, 1, 2, 3, 2, 1},
{2, 3, 2, 1, 2, 1},
{1, 1, 1, 3, 2, 3},
{1, 3, 1, 1, 2, 3},
{1, 3, 1, 3, 2, 1}, // 35
{1, 1, 2, 3, 1, 3},
{1, 3, 2, 1, 1, 3},
{1, 3, 2, 3, 1, 1},
{2, 1, 1, 3, 1, 3},
{2, 3, 1, 1, 1, 3}, // 40
{2, 3, 1, 3, 1, 1},
{1, 1, 2, 1, 3, 3},
{1, 1, 2, 3, 3, 1},
{1, 3, 2, 1, 3, 1},
{1, 1, 3, 1, 2, 3}, // 45
{1, 1, 3, 3, 2, 1},
{1, 3, 3, 1, 2, 1},
{3, 1, 3, 1, 2, 1},
{2, 1, 1, 3, 3, 1},
{2, 3, 1, 1, 3, 1}, // 50
{2, 1, 3, 1, 1, 3},
{2, 1, 3, 3, 1, 1},
{2, 1, 3, 1, 3, 1},
{3, 1, 1, 1, 2, 3},
{3, 1, 1, 3, 2, 1}, // 55
{3, 3, 1, 1, 2, 1},
{3, 1, 2, 1, 1, 3},
{3, 1, 2, 3, 1, 1},
{3, 3, 2, 1, 1, 1},
{3, 1, 4, 1, 1, 1}, // 60
{2, 2, 1, 4, 1, 1},
{4, 3, 1, 1, 1, 1},
{1, 1, 1, 2, 2, 4},
{1, 1, 1, 4, 2, 2},
{1, 2, 1, 1, 2, 4}, // 65
{1, 2, 1, 4, 2, 1},
{1, 4, 1, 1, 2, 2},
{1, 4, 1, 2, 2, 1},
{1, 1, 2, 2, 1, 4},
{1, 1, 2, 4, 1, 2}, // 70
{1, 2, 2, 1, 1, 4},
{1, 2, 2, 4, 1, 1},
{1, 4, 2, 1, 1, 2},
{1, 4, 2, 2, 1, 1},
{2, 4, 1, 2, 1, 1}, // 75
{2, 2, 1, 1, 1, 4},
{4, 1, 3, 1, 1, 1},
{2, 4, 1, 1, 1, 2},
{1, 3, 4, 1, 1, 1},
{1, 1, 1, 2, 4, 2}, // 80
{1, 2, 1, 1, 4, 2},
{1, 2, 1, 2, 4, 1},
{1, 1, 4, 2, 1, 2},
{1, 2, 4, 1, 1, 2},
{1, 2, 4, 2, 1, 1}, // 85
{4, 1, 1, 2, 1, 2},
{4, 2, 1, 1, 1, 2},
{4, 2, 1, 2, 1, 1},
{2, 1, 2, 1, 4, 1},
{2, 1, 4, 1, 2, 1}, // 90
{4, 1, 2, 1, 2, 1},
{1, 1, 1, 1, 4, 3},
{1, 1, 1, 3, 4, 1},
{1, 3, 1, 1, 4, 1},
{1, 1, 4, 1, 1, 3}, // 95
{1, 1, 4, 3, 1, 1},
{4, 1, 1, 1, 1, 3},
{4, 1, 1, 3, 1, 1},
{1, 1, 3, 1, 4, 1},
{1, 1, 4, 1, 3, 1}, // 100
{3, 1, 1, 1, 4, 1},
{4, 1, 1, 1, 3, 1},
{2, 1, 1, 4, 1, 2},
{2, 1, 1, 2, 1, 4},
{2, 1, 1, 2, 3, 2}, // 105
{2, 3, 3, 1, 1, 1, 2}
};
private int xyz=0;
private int xyz_num=0;
public qrcodeUtil(){
}
/*
* 为了使线条变少,采用codeC与codeB交替使用
* */
private StringBuffer code128jx(String code){
StringBuffer sbf=new StringBuffer("");
String code_bsm="";String code_bsm_old="";
if(code==null||code.equals("")){
return sbf;
}
int[] arr=new int[6];
char[] chars = code.toCharArray();
int a=0;int b=0;int c=0;int d=0;int e=0;
for(int i=0;i
continue;
}
System.out.println(i);
a=(int)chars[i]-32;
boolean flag=false;
if(a>=16&&a<=25){
if(i
if(c>=16&&c<=25){
flag=true;
}
}
}
code_bsm_old=code_bsm;
if(flag){
b+=2;
code_bsm="C";
d=Integer.parseInt(code.substring(i,i+2));
arr=CODE_PATTERNS[d];
}
else{
b+=1;
code_bsm="B";
d=a;
arr=CODE_PATTERNS[a];
}
if(i==0){//65==103
sbf=codeSbf(sbf,CODE_PATTERNS[(int)code_bsm.toCharArray()[0]+38]);
xyz+=(int)code_bsm.toCharArray()[0]+38;
}else{
if(!code_bsm.equals(code_bsm_old)){
sbf=codeSbf(sbf,CODE_PATTERNS[(int)code_bsm_old.toCharArray()[0]+33]);
xyz_num++;
xyz+=xyz_num*((int)code_bsm_old.toCharArray()[0]+33);
}
}
xyz_num++;
xyz+=xyz_num*d;
sbf=codeSbf(sbf,arr);
}
int y=xyz%103;
sbf=codeSbf(sbf,CODE_PATTERNS[y]);
sbf=codeSbf(sbf,CODE_PATTERNS[106]);
return sbf;
};
private StringBuffer codeSbf(StringBuffer sbf,int[] arr){
//System.out.println();
for(int m=0;m
sbf.append(arr[m]);
}
System.out.println();
return sbf;
}
public BufferedImage createImage(int width,int height,StringBuffer sbf,String code){
int jj=3;//图片与字体的间距
int bl=5;//图片与字体的高度比例为5:1
String[] arr=sbf.toString().split("");
int w=0;int l=0;
width=100;height=40;
for(int i=0;i
}
width=width-w<40?w+40:width;
width=(width-w)/2==1?(width+1):width;
height=height-27<20?47:height;
int dpHeight=5*(height-23)/6;
int fontHeight=height-23-dpHeight;
l=(width-w)/2;
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
Graphics graphic = image.getGraphics();
Graphics2D g2d=(Graphics2D)graphic;
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
for(int i=0;i
g2d.setColor(Color.BLACK);
for(int j=0;j
}
//graphic.drawRect(l,10,Integer.parseInt(arr[i]),10);
}else{
g2d.setColor(Color.WHITE);
}
l+=Integer.parseInt(arr[i]);
}
// 画字符
g2d.setColor(Color.BLACK);
fontHeight=fontHeight<8?8:fontHeight;
int font_size=(int)(96*fontHeight/72);
font_size=12;
Font f=new Font("宋体",Font.PLAIN,font_size);
FontMetrics fm = sun.font.FontDesignMetrics.getMetrics(f);
g2d.setFont(f);
int fontLeftWidth=(width-fm.stringWidth(code))/2;
for (int i = 0; i
g2d.drawString(code.substring(i,i+1),left,13+dpHeight+fontHeight);
}
return image;
}
public void drawImage(BufferedImage image,String address,String code){
try {
ImageIO.write(image, "jpg", new File(address+"//"+code+".jpg"));
} catch (IOException e) {
e.printStackTrace();
}
}
public static void main(String[] args) {
qrcodeUtil qrcode=new qrcodeUtil();
String code="111aaaa1";
StringBuffer sbf=qrcode.code128jx(code);
qrcode.drawImage(qrcode.createImage(100,40,sbf,code),"D://code",code);
}
}