前段時間因為工作需要,要實現將一段文字或者url生成二維碼,然后中間附上logo,下方正中間附上文字的功能。
上網找了幾篇教程學習了下,由於沒有保存借鑒的博文鏈接,所以就沒po上參考文章的鏈接啦,感謝幾位博主的分享~
大概的實現效果如下圖所示:
實現步驟:
(1)導入java_ZXing_jar包,點此下載jar包
(2)編寫畫二維碼代碼

1 package QRCode; 2 3 import com.google.zxing.common.BitMatrix; 4 import javax.imageio.ImageIO; 5 import java.io.File; 6 import java.io.OutputStream; 7 import java.io.IOException; 8 import java.awt.image.BufferedImage; 9 10 public final class MatrixToImageWriter { 11 12 private static final int BLACK = 0xFF000000; 13 private static final int WHITE = 0xFFFFFFFF; 14 15 private MatrixToImageWriter() {} 16 17 18 public static BufferedImage toBufferedImage(BitMatrix matrix) { 19 int width = matrix.getWidth(); 20 int height = matrix.getHeight(); 21 BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB); 22 for (int x = 0; x < width; x++) { 23 for (int y = 0; y < height; y++) { 24 image.setRGB(x, y, matrix.get(x, y) ? BLACK : WHITE); 25 } 26 } 27 return image; 28 } 29 30 31 public static void writeToFile(BitMatrix matrix, String format, File file) 32 throws IOException { 33 BufferedImage image = toBufferedImage(matrix); 34 if (!ImageIO.write(image, format, file)) { 35 throw new IOException("Could not write an image of format " + format + " to " + file); 36 } 37 } 38 39 40 public static void writeToStream(BitMatrix matrix, String format, OutputStream stream) 41 throws IOException { 42 BufferedImage image = toBufferedImage(matrix); 43 if (!ImageIO.write(image, format, stream)) { 44 throw new IOException("Could not write an image of format " + format); 45 } 46 } 47 48 }
(3)編寫一個類,用來設置中間logo的屬性(注:代碼中“照片的1/6”,應該是“二維碼圖片的1/6”,懶得重新上傳代碼,特此注釋下)

1 package QRCode; 2 3 import java.awt.Color; 4 5 public class LogoConfig { 6 // logo默認邊框顏色 7 public static final Color DEFAULT_BORDERCOLOR = Color.WHITE; 8 // logo默認邊框寬度 9 public static final int DEFAULT_BORDER = 2; 10 // logo大小默認為照片的1/6 11 public static final int DEFAULT_LOGOPART = 6; 12 13 private final int border = DEFAULT_BORDER; 14 private final Color borderColor; 15 private final int logoPart; 16 17 /** 18 * Creates a default config with on color {@link #BLACK} and off color 19 * {@link #WHITE}, generating normal black-on-white barcodes. 20 */ 21 public LogoConfig() 22 { 23 this(DEFAULT_BORDERCOLOR, DEFAULT_LOGOPART); 24 } 25 26 public LogoConfig(Color borderColor, int logoPart) 27 { 28 this.borderColor = borderColor; 29 this.logoPart = logoPart; 30 } 31 32 public Color getBorderColor() 33 { 34 return borderColor; 35 } 36 37 public int getBorder() 38 { 39 return border; 40 } 41 42 public int getLogoPart() 43 { 44 return logoPart; 45 } 46 }
(4)為二維碼圖片添加logo

1 /** 2 * 給二維碼圖片添加Logo 3 * 4 * @param qrPic 5 * @param logoPic 6 */ 7 public static void addLogo_QRCode(File qrPic, File logoPic, LogoConfig logoConfig) 8 { 9 try 10 { 11 if (!qrPic.isFile() || !logoPic.isFile()) 12 { 13 System.out.print("file not find !"); 14 System.exit(0); 15 } 16 17 /** 18 * 讀取二維碼圖片,並構建繪圖對象 19 */ 20 BufferedImage image = ImageIO.read(qrPic); 21 Graphics2D g = image.createGraphics(); 22 23 /** 24 * 讀取Logo圖片 25 */ 26 BufferedImage logo = ImageIO.read(logoPic); 27 28 int widthLogo = image.getWidth()/logoConfig.getLogoPart(); 29 // int heightLogo = image.getHeight()/logoConfig.getLogoPart(); 30 int heightLogo = image.getWidth()/logoConfig.getLogoPart(); //保持二維碼是正方形的 31 32 // 計算圖片放置位置 33 int x = (image.getWidth() - widthLogo) / 2; 34 int y = (image.getHeight() - heightLogo) / 2 ; 35 36 37 //開始繪制圖片 38 g.drawImage(logo, x, y, widthLogo, heightLogo, null); 39 g.drawRoundRect(x, y, widthLogo, heightLogo, 10, 10); 40 g.setStroke(new BasicStroke(logoConfig.getBorder())); 41 g.setColor(logoConfig.getBorderColor()); 42 g.drawRect(x, y, widthLogo, heightLogo); 43 44 g.dispose(); 45 46 ImageIO.write(image, "jpeg", new File("D:/newPic.jpg")); 47 } 48 catch (Exception e) 49 { 50 e.printStackTrace(); 51 } 52 }
(5)為添加好logo的二維碼圖片添加文字

1 /** 2 * @為圖片添加文字 3 * @param pressText 文字 4 * @param newImg 帶文字的圖片 5 * @param targetImg 需要添加文字的圖片 6 * @param fontStyle 7 * @param color 8 * @param fontSize 9 * @param width 10 * @param heigh 11 */ 12 public static void pressText(String pressText, String newImg, String targetImg, int fontStyle, Color color, int fontSize, int width, int height) { 13 14 //計算文字開始的位置 15 //x開始的位置:(圖片寬度-字體大小*字的個數)/2 16 int startX = (width-(fontSize*pressText.length()))/2; 17 //y開始的位置:圖片高度-(圖片高度-圖片寬度)/2 18 int startY = height-(height-width)/2; 19 20 try { 21 File file = new File(targetImg); 22 Image src = ImageIO.read(file); 23 int imageW = src.getWidth(null); 24 int imageH = src.getHeight(null); 25 BufferedImage image = new BufferedImage(imageW, imageH, BufferedImage.TYPE_INT_RGB); 26 Graphics g = image.createGraphics(); 27 g.drawImage(src, 0, 0, imageW, imageH, null); 28 g.setColor(color); 29 g.setFont(new Font(null, fontStyle, fontSize)); 30 g.drawString(pressText, startX, startY); 31 g.dispose(); 32 33 FileOutputStream out = new FileOutputStream(newImg); 34 ImageIO.write(image, "JPEG", out); 35 JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out); 36 encoder.encode(image); 37 out.close(); 38 System.out.println("image press success"); 39 } catch (Exception e) { 40 System.out.println(e); 41 } 42 }
(6)上面功能寫好后,可以綜合一下進行測試

1 public static void main(String args[]) { 2 try { 3 //二維碼表示的內容 4 String content = "http://www.cnblogs.com/"; 5 6 //存放logo的文件夾 7 String path = "E:/QRCodeImage"; 8 9 MultiFormatWriter multiFormatWriter = new MultiFormatWriter(); 10 11 @SuppressWarnings("rawtypes") 12 Map hints = new HashMap(); 13 14 //設置UTF-8, 防止中文亂碼 15 hints.put(EncodeHintType.CHARACTER_SET, "UTF-8"); 16 //設置二維碼四周白色區域的大小 17 hints.put(EncodeHintType.MARGIN,1); 18 //設置二維碼的容錯性 19 hints.put(EncodeHintType.ERROR_CORRECTION, ErrorCorrectionLevel.H); 20 21 //width:圖片完整的寬;height:圖片完整的高 22 //因為要在二維碼下方附上文字,所以把圖片設置為長方形(高大於寬) 23 int width = 400; 24 int height = 450; 25 26 //畫二維碼,記得調用multiFormatWriter.encode()時最后要帶上hints參數,不然上面設置無效 27 BitMatrix bitMatrix = multiFormatWriter.encode(content, BarcodeFormat.QR_CODE, width, height, hints); 28 29 //qrcFile用來存放生成的二維碼圖片(無logo,無文字) 30 File qrcFile = new File(path,"myPicture.jpg"); 31 //logoFile用來存放帶有logo的二維碼圖片(二維碼+logo,無文字) 32 File logoFile = new File(path,"logo.jpg"); 33 34 //開始畫二維碼 35 MatrixToImageWriter.writeToFile(bitMatrix, "jpg", qrcFile); 36 37 //在二維碼中加入圖片 38 LogoConfig logoConfig = new LogoConfig(); //LogoConfig中設置Logo的屬性 39 addLogo_QRCode(qrcFile, logoFile, logoConfig); 40 41 42 int font = 18; //字體大小 43 int fontStyle = 1; //字體風格 44 45 //用來存放帶有logo+文字的二維碼圖片 46 String newImageWithText = "D:/imageWithText.jpg"; 47 //帶有logo的二維碼圖片 48 String targetImage = "D:/newPic.jpg"; 49 //附加在圖片上的文字信息 50 String text = "文字測試一二三四五六123"; 51 52 //在二維碼下方添加文字(文字居中) 53 pressText(text, newImageWithText, targetImage, fontStyle, Color.BLUE, font, width, height) ; 54 55 } catch (Exception e) { 56 e.printStackTrace(); 57 } 58 }
注意:部分ZXing的jar包導入后,配置EncodeHintType.MARGIN會報錯
使用上面附上的java_ZXing_jar包即可。
分享就到此結束啦~~