Java實現二維碼新增文字內容
阿新 • • 發佈:2018-11-08
import java.awt.BasicStroke;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.Shape;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.geom.RoundRectangle2D;
import java.awt.image.BufferedImage;
import java.io.FileInputStream;
import java.io.FileOutputStream;
import javax.imageio.ImageIO;
public class Logo {
/**
* 二維碼大小
*/
private static final int QRCODE_SIZE = 412;
public static void main(String[] args) throws Exception {
FileInputStream fis = new FileInputStream("E:\\ceshi.png");
BufferedImage read = ImageIO.read(fis);
String[] contents = { "二維碼" , "文字或圖片", "合併後仍然可以用","你可以試一下喲~" };
Integer[] perContentMaxLength = { 7, 5 };
mergeImage(read, contents, perContentMaxLength);
FileOutputStream fos = new FileOutputStream("E:\\ceshi_new.png");
ImageIO.write(read, "PNG", fos);
fos.close();
System.out.println("--------OK--------" );
}
/**
* 在給定的圖片或者二維碼上新增LOGO,以二維碼為例 此處LOGO內容是將文字內容新增到二維碼上
* LOGO中的文字最後一行與底部捱得近,這是double轉int時損失精度導致的
*
* @param source
* 原二維碼
* @param contents
* 在二維碼上新增文字內容,每個元素在LOGO上佔一行
* @param perContentMaxLength
* 指定每個元素最長的文字欄位,超出的將被捨去
* @throws Exception
*/
private static void mergeImage(BufferedImage source, String[] contents,
Integer[] perContentMaxLength) throws Exception {
if (null == contents || contents.length < 1) {
return;
}
// LOGO的長度和寬度
int width = 100;
int height = 100;
// 建立原圖的幾何圖形物件
Graphics2D graph = source.createGraphics();
// 計算除去LOGO外其他部分的長和寬的一半
int x = (QRCODE_SIZE - width) / 2;
int y = (QRCODE_SIZE - height) / 2;
// 建立LOGO影象物件
BufferedImage tag = new BufferedImage(width, height,
BufferedImage.TYPE_INT_RGB);
// 獲取LOGO的幾何圖形物件
Graphics2D g2 = (Graphics2D) tag.getGraphics();
// 設定背景色
g2.setBackground(Color.WHITE);
// 設定畫筆,設定Paint屬性
g2.setPaint(Color.BLACK);
g2.clearRect(0, 0, width, height);
Font font = new Font("微軟雅黑", Font.BOLD, 12);
g2.setFont(font);
if (null != contents && contents.length > 0) {
// 獲取操作LOGO的幾何圖形的操作文字的物件
FontRenderContext context = g2.getFontRenderContext();
// 將LOGO的高平分為字串陣列長度份
double y2 = height / contents.length;
for (int i = 0; i < contents.length; i++) {
String content = contents[i];
if (null != perContentMaxLength
&& i < perContentMaxLength.length) {
if (content.length() > perContentMaxLength[i]) {
content = content.substring(0, perContentMaxLength[i]);
}
}
// 通過設定字串獲取到字串在LOGO影象域中的資訊
Rectangle2D bounds = font.getStringBounds(content, context);
// 獲取LOGO幾何圖形中的當前字串所佔的寬度bounds.getWidth(),並計算字串畫素X的起始位置,這裡除以2是為了字串居中顯示
double x2 = (width - bounds.getWidth()) / 2;
// 獲取LOGO幾何圖形中的當前字串所在的高度,y2是平均分的字串陣列的高度
double y3 = (y2 + bounds.getHeight()) / 2;
// 計算字串畫素y的起始位置
double y4 = y2 * i + y3;
g2.drawString(content, (int) x2, (int) y4);
}
}
// 將LOGO修改後的圖形整合到原圖上
graph.drawImage(tag, x, y, width, height, null);
Shape shape = new RoundRectangle2D.Float(x, y, width, width, 6, 6);
graph.setStroke(new BasicStroke(3f));
graph.draw(shape);
graph.dispose();
g2.dispose();
}
}