使用Zxing實現(xiàn)二維碼生成器內(nèi)嵌圖片
使用Zxing實現(xiàn)二維碼生成器內(nèi)嵌圖片,具有一定的參考價值,具體如下:
基本思路是先使用zxing生成的二維碼圖片,然后讀取圖片,在其中插入圖標(biāo),然后整個輸出圖片。
最近的項目中需要生成二維碼,找了幾個例子綜合下,做出了最后的效果,二維碼可以生成圖片格式(jpg等)或者在web頁面上顯示,此片文章僅作記錄,雷同之處多多,包涵。。。。
注:需要Zxing包裝的工具類,大概的流程是讀取內(nèi)嵌的圖片,將內(nèi)容轉(zhuǎn)化成二維碼,將圖片內(nèi)嵌到二維碼中,出圖。
下面是完整代碼:
import Java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Graphics2D;
import java.awt.Image;
import java.awt.Shape;
import java.awt.geom.AffineTransform;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.util.HashMap;
import java.util.Map;
import javax.imageio.ImageIO;
import com.google.zxing.BarcodeFormat;
import com.google.zxing.EncodeHintType;
import com.google.zxing.MultiFormatWriter;
import com.google.zxing.WriterException;
import com.google.zxing.common.BitMatrix;
import com.google.zxing.qrcode.decoder.ErrorCorrectionLevel;
public class Zxing {
private static final int BLACK = 0xFF000000;
private static final int WHITE = 0xFFFFFFFF;
// 圖片寬度的一般
private static final int IMAGE_WIDTH = 80;
private static final int IMAGE_HEIGHT = 80;
private static final int IMAGE_HALF_WIDTH = IMAGE_WIDTH / 2;
private static final int FRAME_WIDTH = 2;
// 二維碼寫碼器
private static MultiFormatWriter mutiWriter = new MultiFormatWriter();
public static void main(String[] args) {
try {
//BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, 400, 400,hints);
String content="13400000000";//二維碼的內(nèi)容
BufferedImage image = genBarcode(content, 400, 400, "F:\\amazed.png");
if (!ImageIO.write(image, "jpg", new File("F:\\2122.jpg"))) {
throw new IOException("Could not write an image of format ");
}
/**
//將上面的代碼換成此處,使用流讀入到頁面即可
OutputStream os = response.getOutputStream();
if (!ImageIO.write(image, "jpg",os)) {
throw new IOException("Could not write an image of format ");
}
**/
} catch (WriterException e) {
e.printStackTrace();
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
private BufferedImage toBufferedImage(BitMatrix matrix) {
int width = matrix.getWidth();
int height = matrix.getHeight();
BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int x = 0; x < width; x++) {
for (int y = 0; y < height; y++) {
image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE);
}
}
return image;
}
private static BufferedImage genBarcode(String content, int width,
int height, String srcImagePath) throws WriterException,
IOException {
// 讀取源圖像
BufferedImage scaleImage = scale(srcImagePath, IMAGE_WIDTH,
IMAGE_HEIGHT, true);
int[][] srcPixels = new int[IMAGE_WIDTH][IMAGE_HEIGHT];
for (int i = 0; i < scaleImage.getWidth(); i++) {
for (int j = 0; j < scaleImage.getHeight(); j++) {
srcPixels[i][j] = scaleImage.getRGB(i, j);
}
}
Map<EncodeHintType, Object> hint = new HashMap<EncodeHintType, Object>();
hint.put(EncodeHintType.CHARACTER_SET, "utf-8"); //內(nèi)容編碼
hint.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H);//錯誤等級
hint.put(EncodeHintType.MARGIN, 1); //設(shè)置二維碼外邊框的空白區(qū)域的寬度
// 生成二維碼
BitMatrix matrix = mutiWriter.encode(content, BarcodeFormat.QR_CODE,
width, height, hint);
// 二維矩陣轉(zhuǎn)為一維像素數(shù)組
int halfW = matrix.getWidth() / 2;
int halfH = matrix.getHeight() / 2;
int[] pixels = new int[width * height];
for (int y = 0; y < matrix.getHeight(); y++) {
for (int x = 0; x < matrix.getWidth(); x++) {
// 讀取圖片
if (x > halfW - IMAGE_HALF_WIDTH
&& x < halfW + IMAGE_HALF_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH
&& y < halfH + IMAGE_HALF_WIDTH) {
pixels[y * width + x] = srcPixels[x - halfW
+ IMAGE_HALF_WIDTH][y - halfH + IMAGE_HALF_WIDTH];
}
// 在圖片四周形成邊框
else if ((x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
&& x < halfW - IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
+ IMAGE_HALF_WIDTH + FRAME_WIDTH)
|| (x > halfW + IMAGE_HALF_WIDTH - FRAME_WIDTH
&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
+ IMAGE_HALF_WIDTH + FRAME_WIDTH)
|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH - IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
- IMAGE_HALF_WIDTH + FRAME_WIDTH)
|| (x > halfW - IMAGE_HALF_WIDTH - FRAME_WIDTH
&& x < halfW + IMAGE_HALF_WIDTH + FRAME_WIDTH
&& y > halfH + IMAGE_HALF_WIDTH - FRAME_WIDTH && y < halfH
+ IMAGE_HALF_WIDTH + FRAME_WIDTH)) {
pixels[y * width + x] = 0xfffffff;
} else {
// 此處可以修改二維碼的顏色,可以分別制定二維碼和背景的顏色;
pixels[y * width + x] = matrix.get(x, y) ? 0xff000000
: 0xfffffff;
}
}
}
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
image.getRaster().setDataElements(0, 0, width, height, pixels);
return image;
}
/**
* 把傳入的原始圖像按高度和寬度進行縮放,生成符合要求的圖標(biāo)
*
* @param srcImageFile
* 源文件地址
* @param height
* 目標(biāo)高度
* @param width
* 目標(biāo)寬度
* @param hasFiller
* 比例不對時是否需要補白:true為補白; false為不補白;
* @throws IOException
*/
private static BufferedImage scale(String srcImageFile, int height,
int width, boolean hasFiller) throws IOException {
double ratio = 0.0; // 縮放比例
File file = new File(srcImageFile);
BufferedImage srcImage = ImageIO.read(file);
Image destImage = srcImage.getScaledInstance(width, height,
BufferedImage.SCALE_SMOOTH);
// 計算比例
if ((srcImage.getHeight() > height) || (srcImage.getWidth() > width)) {
if (srcImage.getHeight() > srcImage.getWidth()) {
ratio = (new Integer(height)).doubleValue()
/ srcImage.getHeight();
} else {
ratio = (new Integer(width)).doubleValue()
/ srcImage.getWidth();
}
AffineTransformOp op = new AffineTransformOp(
AffineTransform.getScaleInstance(ratio, ratio), null);
destImage = op.filter(srcImage, null);
}
if (hasFiller) {// 補白
BufferedImage image = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
Graphics2D graphic = image.createGraphics();
graphic.setColor(Color.PINK);
graphic.fillRect(10, 10, width, height);
graphic.drawRect(100, 360, width, height);
if (width == destImage.getWidth(null)) {
graphic.drawImage(destImage, 0,
(height - destImage.getHeight(null)) / 2,
destImage.getWidth(null), destImage.getHeight(null),
Color.white, null);
Shape shape = new RoundRectangle2D.Float(0, (height - destImage.getHeight(null)) / 2, width, width, 20, 20);
graphic.setStroke(new BasicStroke(5f));
graphic.draw(shape);
}
else {
graphic.drawImage(destImage,
(width - destImage.getWidth(null)) / 2, 0,
destImage.getWidth(null), destImage.getHeight(null),
Color.white, null);
Shape shape = new RoundRectangle2D.Float((width - destImage.getWidth(null)) / 2, 0, width, width, 20, 20);
graphic.setStroke(new BasicStroke(5f));
graphic.draw(shape);
}
graphic.dispose();
destImage = image;
}
return (BufferedImage) destImage;
}
}
以上就是本文的全部內(nèi)容,希望對大家的學(xué)習(xí)有所幫助,也希望大家多多支持腳本之家。
相關(guān)文章
windows java.exe內(nèi)存暴漲解決、idea跑java\ tomcat內(nèi)存無限增長
這篇文章主要介紹了windows java.exe內(nèi)存暴漲解決、idea跑 java\ tomcat內(nèi)存無限增長,具有很好的參考價值,希望對大家有所幫助。一起跟隨小編過來看看吧2021-01-01
解決jhipster修改jdl生成的實體類報錯:liquibase.exception.ValidationFailed
這篇文章主要介紹了解決jhipster修改jdl生成的實體類報錯:liquibase.exception.ValidationFailedException: Validation Failed問題,具有很好的參考價值,希望對大家有所幫助,如有錯誤或未考慮完全的地方,望不吝賜教2023-11-11

