二維碼的生成與解析。有多種途徑。我選擇用大品牌,google老大的zxing。
鐘山網(wǎng)站建設(shè)公司成都創(chuàng)新互聯(lián),鐘山網(wǎng)站設(shè)計(jì)制作,有大型網(wǎng)站制作公司豐富經(jīng)驗(yàn)。已為鐘山1000多家提供企業(yè)網(wǎng)站建設(shè)服務(wù)。企業(yè)網(wǎng)站搭建\外貿(mào)網(wǎng)站制作要多少錢,請(qǐng)找那個(gè)售后服務(wù)好的鐘山做網(wǎng)站的公司定做!
gitHub鏈接是(我用的3.0.0,已經(jīng)是nio了)
Java代碼 收藏代碼
// 其中輸出圖像和讀取圖像的類在core包
MultiFormatReader
MultiFormatWriter
// 生成矩陣的類在javase的包里
MatrixToImageWriter
pom.xml中的配置為
Xml代碼 收藏代碼
project xmlns="" xmlns:xsi=""
xsi:schemaLocation=" "
modelVersion4.0.0/modelVersion
groupIdcom.shihy/groupId
artifactIdqrcode/artifactId
version0.0.1-SNAPSHOT/version
packagingjar/packaging
nameqrcode/name
url;/url
properties
project.build.sourceEncodingUTF-8/project.build.sourceEncoding
/properties
dependencies
dependency
groupIdcom.google.zxing/groupId
artifactIdcore/artifactId
version3.0.0/version
/dependency
dependency
groupIdcom.google.zxing/groupId
artifactIdjavase/artifactId
version3.0.0/version
/dependency
dependency
groupIdjunit/groupId
artifactIdjunit/artifactId
version4.10/version
/dependency
dependency
groupIdcom.alibaba/groupId
artifactIdfastjson/artifactId
version1.1.29/version
/dependency
/dependencies
/project
生成圖像與解析圖像的測(cè)試工具類:
Java代碼 收藏代碼
package com.polysaas.edu.qrcode;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.nio.file.FileSystems;
import java.nio.file.Path;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import org.junit.Test;
import com.alibaba.fastjson.JSONObject;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.Binarizer;
import com.google.zxing.BinaryBitmap;
import com.google.zxing.DecodeHintType;
import com.google.zxing.EncodeHintType;
import com.google.zxing.LuminanceSource;
import com.google.zxing.MultiFormatReader;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.NotFoundException;
import com.google.zxing.Result;
import com.google.zxing.WriterException;
import com.google.zxing.client.j2se.BufferedImageLuminanceSource;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.common.HybridBinarizer;
public class QRCodeTest {
/**
* 生成圖像
*
* @throws WriterException
* @throws IOException
*/
@Test
public void testEncode() throws WriterException, IOException {
String filePath = "D://";
String fileName = "zxing.png";
JSONObject json = new JSONObject();
json.put(
"zxing",
"");
json.put("author", "shihy");
String content = json.toJSONString();// 內(nèi)容
int width = 200; // 圖像寬度
int height = 200; // 圖像高度
String format = "png";// 圖像類型
MapEncodeHintType, Object hints = new HashMapEncodeHintType, Object();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(content,
BarcodeFormat.QR_CODE, width, height, hints);// 生成矩陣
Path path = FileSystems.getDefault().getPath(filePath, fileName);
MatrixToImageWriter.writeToPath(bitMatrix, format, path);// 輸出圖像
System.out.println("輸出成功.");
}
/**
* 解析圖像
*/
@Test
public void testDecode() {
String filePath = "D://zxing.png";
BufferedImage image;
try {
image = ImageIO.read(new File(filePath));
LuminanceSource source = new BufferedImageLuminanceSource(image);
Binarizer binarizer = new HybridBinarizer(source);
BinaryBitmap binaryBitmap = new BinaryBitmap(binarizer);
MapDecodeHintType, Object hints = new HashMapDecodeHintType, Object();
hints.put(DecodeHintType.CHARACTER_SET, "UTF-8");
Result result = new MultiFormatReader().decode(binaryBitmap, hints);// 對(duì)圖像進(jìn)行解碼
JSONObject content = JSONObject.parseObject(result.getText());
System.out.println("圖片中內(nèi)容: ");
System.out.println("author: " + content.getString("author"));
System.out.println("zxing: " + content.getString("zxing"));
System.out.println("圖片中格式: ");
System.out.println("encode: " + result.getBarcodeFormat());
} catch (IOException e) {
e.printStackTrace();
} catch (NotFoundException e) {
e.printStackTrace();
}
}
}
引用spire.barcode.jar包
//創(chuàng)建BarcodeSettings對(duì)象
BarcodeSettings?settings?=?new?BarcodeSettings();
//設(shè)置條碼類型為
QR二維碼settings.setType(BarCodeType.QR_Code);???????
//設(shè)置二維碼數(shù)據(jù)
settings.setData("Hello?123456789");
//設(shè)置二維碼顯示數(shù)據(jù)
settings.setData2D("Hello?123456789");?????
//設(shè)置數(shù)據(jù)類型
settings.setQRCodeDataMode(QRCodeDataMode.Alpha_Number);
//設(shè)置二維碼模型寬度
settings.setX(1.0f);
//設(shè)置二維碼糾錯(cuò)級(jí)別settings.setQRCodeECL(QRCodeECL.H);
//創(chuàng)建BarCodeGenerator實(shí)例
BarCodeGenerator?barCodeGenerator?=?new?BarCodeGenerator(settings);
//根據(jù)settings生成圖像數(shù)據(jù),保存至BufferedImage
BufferedImage?bufferedImage?=?barCodeGenerator.generateImage();
//將圖片數(shù)據(jù)保存為PNG格式
ImageIO.write(bufferedImage,?"png",?new?File("QRCode.png"));
1: 使用SwetakeQRCode在Java項(xiàng)目中生成二維碼
下載地址
或著
這個(gè)是日本人寫的,生成的是我們常見(jiàn)的方形的二維碼
可以用中文
如:5677777ghjjjjj
2: 使用BarCode4j生成條形碼和二維碼
BarCode4j網(wǎng)址:
barcode4j是使用datamatrix的二維碼生成算法,為支持qr的算法
datamatrix是歐美的標(biāo)準(zhǔn),qr為日本的標(biāo)準(zhǔn),
barcode4j一般生成出來(lái)是長(zhǎng)方形的
如:88777alec000yan
這個(gè)博客這方面說(shuō)的挺清楚的:
3:zxing
zxing 這個(gè)是google的
下載地址
Java代碼:
import java.io.File;
import java.util.Hashtable;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.client.j2se.MatrixToImageWriter;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.QRCodeWriter;
public class QRCodeEvents {
public static void main(String []args)throws Exception{
String text = "你好";
int width = 100;
int height = 100;
String format = "png";
Hashtable hints= new Hashtable();
hints.put(EncodeHintType.CHARACTER_SET, "utf-8");
BitMatrix bitMatrix = new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, width, height,hints);
File outputFile = new File("new.png");
MatrixToImageWriter.writeToFile(bitMatrix, format, outputFile);
}
}
4:google chart api就有實(shí)現(xiàn)二維碼的方法
利用這個(gè)api,使用google appengine進(jìn)行實(shí)現(xiàn)。
5:JS生成二維碼
使用jQuery-qrcode生成二維碼
先簡(jiǎn)單說(shuō)一下jquery-qrcode,這個(gè)開(kāi)源的三方庫(kù)(可以從 獲取),
qrcode.js 是實(shí)現(xiàn)二維碼數(shù)據(jù)計(jì)算的核心類,
jquery.qrcode.js 是把它用jquery方式封裝起來(lái)的,用它來(lái)實(shí)現(xiàn)圖形渲染,其實(shí)就是畫圖(支持canvas和table兩種方式)
支持的功能主要有:
Js代碼:
text : "" //設(shè)置二維碼內(nèi)容
Js代碼:
render : "canvas",//設(shè)置渲染方式
width : 256, //設(shè)置寬度
height : 256, //設(shè)置高度
typeNumber : -1, //計(jì)算模式
correctLevel : QRErrorCorrectLevel.H,//糾錯(cuò)等級(jí)
background : "#ffffff",//背景顏色
foreground : "#000000" //前景顏色
使用方式非常簡(jiǎn)單
Js代碼:
jQuery('#output').qrcode({width:200,height:200,correctLevel:0,text:content});
經(jīng)過(guò)簡(jiǎn)單實(shí)踐,
使用canvas方式渲染性能還是非常不錯(cuò)的,但是如果用table方式,性能不太理想,特別是IE9以下的瀏覽器,所以需要自行優(yōu)化一下渲染table的方式,這里就不細(xì)述了。
其實(shí)上面的js有一個(gè)小小的缺點(diǎn),就是默認(rèn)不支持中文。
這跟js的機(jī)制有關(guān)系,jquery-qrcode這個(gè)庫(kù)是采用 charCodeAt() 這個(gè)方式進(jìn)行編碼轉(zhuǎn)換的,
而這個(gè)方法默認(rèn)會(huì)獲取它的 Unicode 編碼,一般的解碼器都是采用UTF-8, ISO-8859-1等方式,
英文是沒(méi)有問(wèn)題,如果是中文,一般情況下Unicode是UTF-16實(shí)現(xiàn),長(zhǎng)度2位,而UTF-8編碼是3位,這樣二維碼的編解碼就不匹配了。
解決方式當(dāng)然是,在二維碼編碼前把字符串轉(zhuǎn)換成UTF-8,具體代碼如下:
function utf16to8(str) {
var out, i, len, c;
out = "";
len = str.length;
for(i = 0; i len; i++) {
c = str.charCodeAt(i);
if ((c = 0x0001) (c = 0x007F)) {
out += str.charAt(i);
} else if (c 0x07FF) {
out += String.fromCharCode(0xE0 | ((c 12) 0x0F));
out += String.fromCharCode(0x80 | ((c 6) 0x3F));
out += String.fromCharCode(0x80 | ((c 0) 0x3F));
} else {
out += String.fromCharCode(0xC0 | ((c 6) 0x1F));
out += String.fromCharCode(0x80 | ((c 0) 0x3F));
}
}
return out;
}
需要的jar: qrcode.jar和 qrcode_swetake.jar,以及一個(gè)工具類,下面有。
package com.sbm.wll.image;
/**
* Java 生成二維碼,解析二維碼
*/
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.io.InputStream;
import java.io.OutputStream;
import javax.imageio.ImageIO;
import com.swetake.util.Qrcode;
import jp.sourceforge.qrcode.QRCodeDecoder;
import jp.sourceforge.qrcode.exception.DecodingFailedException;
public class Image {
/**
* 生成二維碼圖片文件
*
* @param content
* 存儲(chǔ)內(nèi)容
* @param imgPath
* 圖片路徑
* @param imgType
* 圖片類型
* @param size
* 二維碼尺寸
*/
public void encoderQRCode(String content, String imgPath, String imgType, int size) {
try {
BufferedImage bufImg = this.qRCodeCommon(content, imgType, size);
File imgFile = new File(imgPath);
// 生成二維碼QRCode圖片
ImageIO.write(bufImg, imgType, imgFile);
System.out.println("二維碼生成成功,路徑:" + imgPath);
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 生成二維碼,流輸出
*/
public void encoderQRCode(String content, OutputStream output, String imgType, int size) {
try {
BufferedImage bufImg = this.qRCodeCommon(content, imgType, size);
// 生成二維碼QRCode圖片
ImageIO.write(bufImg, imgType, output);
System.out.println("二維碼生成成功,流輸出");
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 生成二維碼(QRCode)圖片的基本方法
*/
private BufferedImage qRCodeCommon(String content, String imgType, int size) {
BufferedImage bufImg = null;
try {
Qrcode qrcodeHandler = new Qrcode();
// 設(shè)置二維碼排錯(cuò)率,可選L(7%)、M(15%)、Q(25%)、H(30%),排錯(cuò)率越高可存儲(chǔ)的信息越少,但對(duì)二維碼清晰度的要求越小
qrcodeHandler.setQrcodeErrorCorrect('M');
qrcodeHandler.setQrcodeEncodeMode('B');
// 設(shè)置設(shè)置二維碼尺寸,取值范圍1-40,值越大尺寸越大,可存儲(chǔ)的信息越大
qrcodeHandler.setQrcodeVersion(size);
// 獲得內(nèi)容的字節(jié)數(shù)組,設(shè)置編碼格式
byte[] contentBytes = content.getBytes("utf-8");
// 圖片尺寸
int imgSize = 67 + 12 * (size - 1);
bufImg = new BufferedImage(imgSize, imgSize, BufferedImage.TYPE_INT_RGB);
Graphics2D gs = bufImg.createGraphics();
// 設(shè)置背景顏色
gs.setBackground(Color.WHITE);
gs.clearRect(0, 0, imgSize, imgSize);
// 設(shè)定圖像顏色 BLACK
gs.setColor(Color.BLACK);
// 設(shè)置偏移量,不設(shè)置可能導(dǎo)致解析出錯(cuò)
int pixoff = 2;
// 輸出內(nèi)容 二維碼