QR码的使用越来越多,可以在很多地方见着,比如火车票、推广产品上等,以下将介绍如何用Java生成QR码以及解码QR码。
1、涉及开源项目:ZXing :一个开源Java类库用于解析多种格式的1D/2D条形码。目标是能够对QR编码、Data Matrix、UPC的1D条形码进行解码。 其提供了多种平台下的客户端包括:J2ME、J2SE和Android。---用来解码QRcoded-project:Kazuhiko Arase的个人项目(他具体是谁不清楚,日本的),提供丰富的配置参数,非常灵活---用来生成QR code2、效果图:生成QR code解码QR code
3、使用d-project生成QRcdoe 1)将com.d_project.qrcode.jar引入工程 2)QRcodeAction代码: public void generate(RequestContext rc)
throws UnsupportedEncodingException, IOException, ServletException {
//待转数据
String data = rc.param("data", "http://osctools.net/qr");
//输出图片类型
String output = rc.param("output", "image/jpeg");
int type = rc.param("type", 4);
if (type < 0 || 10 < type) {
return;
}
int margin = rc.param("margin", 10);
if (margin < 0 || 32 < margin) {
return;
}
int cellSize = rc.param("size", 4);
if (cellSize < 1 || 4 < cellSize) {
return;
}
int errorCorrectLevel = 0;
try {
errorCorrectLevel = parseErrorCorrectLevel(rc,
rc.param("error", "H"));
} catch (Exception e) {
return;
}
com.d_project.qrcode.QRCode qrcode = null;
try {
qrcode = getQRCode(data, type, errorCorrectLevel);
} catch (Exception e) {
return;
}
if ("image/jpeg".equals(output)) {
BufferedImage image = qrcode.createImage(cellSize, margin);
rc.response().setContentType("image/jpeg");
OutputStream out = new BufferedOutputStream(rc.response()
.getOutputStream());
try {
ImageIO.write(image, "jpeg", out);
} finally {
out.close();
}
} else if ("image/png".equals(output)) {
BufferedImage image = qrcode.createImage(cellSize, margin);
rc.response().setContentType("image/png");
OutputStream out = new BufferedOutputStream(rc.response()
.getOutputStream());
try {
ImageIO.write(image, "png", out);
} finally {
out.close();
}
} else if ("image/gif".equals(output)) {
GIFImage image = createGIFImage(qrcode, cellSize, margin);
rc.response().setContentType("image/gif");
OutputStream out = new BufferedOutputStream(rc.response()
.getOutputStream());
try {
image.write(out);
} finally {
out.close();
}
} else {
return;
}
}
private static int parseErrorCorrectLevel(RequestContext rc, String ecl) {
if ("L".equals(ecl)) {
return ErrorCorrectLevel.L;
} else if ("Q".equals(ecl)) {
return ErrorCorrectLevel.Q;
} else if ("M".equals(ecl)) {
return ErrorCorrectLevel.M;
} else if ("H".equals(ecl)) {
return ErrorCorrectLevel.H;
} else {
throw rc.error("qr_error_correct_error");
}
}
private static QRCode getQRCode(String text, int typeNumber,
int errorCorrectLevel) throws IllegalArgumentException {
if (typeNumber == 0) {
return QRCode.getMinimumQRCode(text, errorCorrectLevel);
} else {
QRCode qr = new QRCode();
qr.setTypeNumber(typeNumber);
qr.setErrorCorrectLevel(errorCorrectLevel);
qr.addData(text);
qr.make();
return qr;
}
}
private static GIFImage createGIFImage(QRCode qrcode, int cellSize,
int margin) throws IOException {
int imageSize = qrcode.getModuleCount() * cellSize + margin * 2;
GIFImage image = new GIFImage(imageSize, imageSize);
for (int y = 0; y < imageSize; y++) {
for (int x = 0; x < imageSize; x++) {
if (margin <= x && x < imageSize - margin && margin <= y
&& y < imageSize - margin) {
int col = (x - margin) / cellSize;
int row = (y - margin) / cellSize;
if (qrcode.isDark(row, col)) {
image.setPixel(x, y, 0);
} else {
image.setPixel(x, y, 1);
}
} else {
image.setPixel(x, y, 1);
}
}
}
return image;
}4、使用ZXing解码QRcode
1)下载Zxing-2.0.zip
2)引入zxing-barcode_core.jar与zxing_barcode_j2se.jar到工程
3)QRcodeAction代码:@PostMethod
@JSONOutputEnabled
public void decode(RequestContext rc) throws IOException {
//存在qrcode的网址
String url = rc.param("url", "");
//待解码的qrcdoe图像
File img = rc.file("qrcode");
if (StringUtils.isBlank(url) && img == null) {
throw rc.error("qr_upload_or_url_null");
}
List<Result> results = new ArrayList<Result>();
Config config = new Config();
Inputs inputs = new Inputs();
config.setHints(buildHints(config));
if (StringUtils.isNotBlank(url)) {
addArgumentToInputs(url, config, inputs);
}
if (img != null) {
inputs.addInput(img.getCanonicalPath());
}
while (true) {
String input = inputs.getNextInput();
if (input == null) {
break;
}
File inputFile = new File(input);
if (inputFile.exists()) {
try {
Result result = decode(inputFile.toURI(), config,rc);
results.add(result);
} catch (IOException e) {
}
} else {
try {
Result result = decode(new URI(input), config,rc);
results.add(result);
} catch (Exception e) {
}
}
}
rc.print(new Gson().toJson(results));
}
private Result decode(URI uri,Config config,RequestContext rc)
throws IOException {
Map<DecodeHintType, ?> hints = config.getHints();
BufferedImage image;
try {
image = ImageIO.read(uri.toURL());
} catch (IllegalArgumentException iae) {
throw rc.error("qr_resource_not_found");
}
if (image == null) {
throw rc.error("qr_could_not_load_image");
}
try {
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result = new MultiFormatReader().decode(bitmap, hints);
return result;
} catch (NotFoundException nfe) {
throw rc.error("qr_no_barcode_found");
}
}
private static Map<DecodeHintType, ?> buildHints(Config config) {
Map<DecodeHintType, Object> hints = new EnumMap<DecodeHintType, Object>(
DecodeHintType.class);
Collection<BarcodeFormat> vector = new ArrayList<BarcodeFormat>(8);
vector.add(BarcodeFormat.UPC_A);
vector.add(BarcodeFormat.UPC_E);
vector.add(BarcodeFormat.EAN_13);
vector.add(BarcodeFormat.EAN_8);
vector.add(BarcodeFormat.RSS_14);
vector.add(BarcodeFormat.RSS_EXPANDED);
if (!config.isProductsOnly()) {
vector.add(BarcodeFormat.CODE_39);
vector.add(BarcodeFormat.CODE_93);
vector.add(BarcodeFormat.CODE_128);
vector.add(BarcodeFormat.ITF);
vector.add(BarcodeFormat.QR_CODE);
vector.add(BarcodeFormat.DATA_MATRIX);
vector.add(BarcodeFormat.AZTEC);
vector.add(BarcodeFormat.PDF_417);
vector.add(BarcodeFormat.CODABAR);
vector.add(BarcodeFormat.MAXICODE);
}
hints.put(DecodeHintType.POSSIBLE_FORMATS, vector);
if (config.isTryHarder()) {
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
}
if (config.isPureBarcode()) {
hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
}
return hints;
}
private static void addArgumentToInputs(String argument, Config config,
Inputs inputs) throws IOException {
File inputFile = new File(argument);
if (inputFile.exists()) {
inputs.addInput(inputFile.getCanonicalPath());
} else {
inputs.addInput(argument);
}
}注意:其中牵涉到的RequestContext类见此处
1、涉及开源项目:ZXing :一个开源Java类库用于解析多种格式的1D/2D条形码。目标是能够对QR编码、Data Matrix、UPC的1D条形码进行解码。 其提供了多种平台下的客户端包括:J2ME、J2SE和Android。---用来解码QRcoded-project:Kazuhiko Arase的个人项目(他具体是谁不清楚,日本的),提供丰富的配置参数,非常灵活---用来生成QR code2、效果图:生成QR code解码QR code
3、使用d-project生成QRcdoe 1)将com.d_project.qrcode.jar引入工程 2)QRcodeAction代码: public void generate(RequestContext rc)
throws UnsupportedEncodingException, IOException, ServletException {
//待转数据
String data = rc.param("data", "http://osctools.net/qr");
//输出图片类型
String output = rc.param("output", "image/jpeg");
int type = rc.param("type", 4);
if (type < 0 || 10 < type) {
return;
}
int margin = rc.param("margin", 10);
if (margin < 0 || 32 < margin) {
return;
}
int cellSize = rc.param("size", 4);
if (cellSize < 1 || 4 < cellSize) {
return;
}
int errorCorrectLevel = 0;
try {
errorCorrectLevel = parseErrorCorrectLevel(rc,
rc.param("error", "H"));
} catch (Exception e) {
return;
}
com.d_project.qrcode.QRCode qrcode = null;
try {
qrcode = getQRCode(data, type, errorCorrectLevel);
} catch (Exception e) {
return;
}
if ("image/jpeg".equals(output)) {
BufferedImage image = qrcode.createImage(cellSize, margin);
rc.response().setContentType("image/jpeg");
OutputStream out = new BufferedOutputStream(rc.response()
.getOutputStream());
try {
ImageIO.write(image, "jpeg", out);
} finally {
out.close();
}
} else if ("image/png".equals(output)) {
BufferedImage image = qrcode.createImage(cellSize, margin);
rc.response().setContentType("image/png");
OutputStream out = new BufferedOutputStream(rc.response()
.getOutputStream());
try {
ImageIO.write(image, "png", out);
} finally {
out.close();
}
} else if ("image/gif".equals(output)) {
GIFImage image = createGIFImage(qrcode, cellSize, margin);
rc.response().setContentType("image/gif");
OutputStream out = new BufferedOutputStream(rc.response()
.getOutputStream());
try {
image.write(out);
} finally {
out.close();
}
} else {
return;
}
}
private static int parseErrorCorrectLevel(RequestContext rc, String ecl) {
if ("L".equals(ecl)) {
return ErrorCorrectLevel.L;
} else if ("Q".equals(ecl)) {
return ErrorCorrectLevel.Q;
} else if ("M".equals(ecl)) {
return ErrorCorrectLevel.M;
} else if ("H".equals(ecl)) {
return ErrorCorrectLevel.H;
} else {
throw rc.error("qr_error_correct_error");
}
}
private static QRCode getQRCode(String text, int typeNumber,
int errorCorrectLevel) throws IllegalArgumentException {
if (typeNumber == 0) {
return QRCode.getMinimumQRCode(text, errorCorrectLevel);
} else {
QRCode qr = new QRCode();
qr.setTypeNumber(typeNumber);
qr.setErrorCorrectLevel(errorCorrectLevel);
qr.addData(text);
qr.make();
return qr;
}
}
private static GIFImage createGIFImage(QRCode qrcode, int cellSize,
int margin) throws IOException {
int imageSize = qrcode.getModuleCount() * cellSize + margin * 2;
GIFImage image = new GIFImage(imageSize, imageSize);
for (int y = 0; y < imageSize; y++) {
for (int x = 0; x < imageSize; x++) {
if (margin <= x && x < imageSize - margin && margin <= y
&& y < imageSize - margin) {
int col = (x - margin) / cellSize;
int row = (y - margin) / cellSize;
if (qrcode.isDark(row, col)) {
image.setPixel(x, y, 0);
} else {
image.setPixel(x, y, 1);
}
} else {
image.setPixel(x, y, 1);
}
}
}
return image;
}4、使用ZXing解码QRcode
1)下载Zxing-2.0.zip
2)引入zxing-barcode_core.jar与zxing_barcode_j2se.jar到工程
3)QRcodeAction代码:@PostMethod
@JSONOutputEnabled
public void decode(RequestContext rc) throws IOException {
//存在qrcode的网址
String url = rc.param("url", "");
//待解码的qrcdoe图像
File img = rc.file("qrcode");
if (StringUtils.isBlank(url) && img == null) {
throw rc.error("qr_upload_or_url_null");
}
List<Result> results = new ArrayList<Result>();
Config config = new Config();
Inputs inputs = new Inputs();
config.setHints(buildHints(config));
if (StringUtils.isNotBlank(url)) {
addArgumentToInputs(url, config, inputs);
}
if (img != null) {
inputs.addInput(img.getCanonicalPath());
}
while (true) {
String input = inputs.getNextInput();
if (input == null) {
break;
}
File inputFile = new File(input);
if (inputFile.exists()) {
try {
Result result = decode(inputFile.toURI(), config,rc);
results.add(result);
} catch (IOException e) {
}
} else {
try {
Result result = decode(new URI(input), config,rc);
results.add(result);
} catch (Exception e) {
}
}
}
rc.print(new Gson().toJson(results));
}
private Result decode(URI uri,Config config,RequestContext rc)
throws IOException {
Map<DecodeHintType, ?> hints = config.getHints();
BufferedImage image;
try {
image = ImageIO.read(uri.toURL());
} catch (IllegalArgumentException iae) {
throw rc.error("qr_resource_not_found");
}
if (image == null) {
throw rc.error("qr_could_not_load_image");
}
try {
LuminanceSource source = new BufferedImageLuminanceSource(image);
BinaryBitmap bitmap = new BinaryBitmap(new HybridBinarizer(source));
Result result = new MultiFormatReader().decode(bitmap, hints);
return result;
} catch (NotFoundException nfe) {
throw rc.error("qr_no_barcode_found");
}
}
private static Map<DecodeHintType, ?> buildHints(Config config) {
Map<DecodeHintType, Object> hints = new EnumMap<DecodeHintType, Object>(
DecodeHintType.class);
Collection<BarcodeFormat> vector = new ArrayList<BarcodeFormat>(8);
vector.add(BarcodeFormat.UPC_A);
vector.add(BarcodeFormat.UPC_E);
vector.add(BarcodeFormat.EAN_13);
vector.add(BarcodeFormat.EAN_8);
vector.add(BarcodeFormat.RSS_14);
vector.add(BarcodeFormat.RSS_EXPANDED);
if (!config.isProductsOnly()) {
vector.add(BarcodeFormat.CODE_39);
vector.add(BarcodeFormat.CODE_93);
vector.add(BarcodeFormat.CODE_128);
vector.add(BarcodeFormat.ITF);
vector.add(BarcodeFormat.QR_CODE);
vector.add(BarcodeFormat.DATA_MATRIX);
vector.add(BarcodeFormat.AZTEC);
vector.add(BarcodeFormat.PDF_417);
vector.add(BarcodeFormat.CODABAR);
vector.add(BarcodeFormat.MAXICODE);
}
hints.put(DecodeHintType.POSSIBLE_FORMATS, vector);
if (config.isTryHarder()) {
hints.put(DecodeHintType.TRY_HARDER, Boolean.TRUE);
}
if (config.isPureBarcode()) {
hints.put(DecodeHintType.PURE_BARCODE, Boolean.TRUE);
}
return hints;
}
private static void addArgumentToInputs(String argument, Config config,
Inputs inputs) throws IOException {
File inputFile = new File(argument);
if (inputFile.exists()) {
inputs.addInput(inputFile.getCanonicalPath());
} else {
inputs.addInput(argument);
}
}注意:其中牵涉到的RequestContext类见此处
解决方案 »
免费领取超大流量手机卡,每月29元包185G流量+100分钟通话, 中国电信官方发货