java 實(shí)現(xiàn)圖片合成,并添加文字
最近公司一個需要,需要把商品的優(yōu)惠卷分享鏈接,生成一個二維碼然后和商品主圖合成一張,并且在新合成的主圖增加商品信息的描述,好了直接看合成后圖片的樣式

下面我就直接貼代碼,首先是Contorller層
/**
* 淘寶二維碼,商品主圖,合成一張圖
*
* @param pictUrl
* @param request
* @param response
* @throws IOException
*/
@RequestMapping("/getTaoBaoqQRCode")
public void getTaoBaoqQRCode(TaoBaoQRCode taoBaoQRCode, HttpServletRequest request,
HttpServletResponse response) throws IOException {
ServletOutputStream os = null;
InputStream buffin = null;
try {
// 二維碼
String couponUlr = "https:" + taoBaoQRCode.getCouponShareUrl();// 高額卷分享鏈接
byte[] imgByte = QrCodeUtil.createQrCode2Bytes(250, 250, couponUlr);
buffin = new ByteArrayInputStream(imgByte);
BufferedImage couponImage = ImageIO.read(buffin);
// 商品主圖
String imageUrl = "https:" + taoBaoQRCode.getPictUrl();
URL url = new URL(imageUrl);
BufferedImage picImage = ImageIO.read(url);
BufferedImage modifyImage =
imageHandleUtil.mergeImage(picImage, couponImage, taoBaoQRCode.getTitle(),
taoBaoQRCode.getReservePrice(), taoBaoQRCode.getZkFinalPrice());
response.setContentType("image/jpg");
os = response.getOutputStream();
ImageIO.write(modifyImage, "jpg", os);
os.flush();
} catch (Exception e) {
LOGGER.error("getTaoBaoqQRCode error");
e.printStackTrace();
} finally {
buffin.close();
os.close();
}
}
二維碼QrCodeUtil 生成幫助類
public class QrCodeUtil {
private static final int DAFAULT_WIDTH = 360;
private static final int DAFAULT_HEIGHT = 360;
private static final Logger LOGGER = LoggerFactory.getLogger(QrCodeUtil.class);
public static String createQrCode(String text) {
return createQrCode(DAFAULT_WIDTH, DAFAULT_HEIGHT, text);
}
public static String createQrCode(int widht, int height, String text) {
HashMap<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
try {
byte[] bytes = createQrCode2Bytes(widht, height, text);
String fileName = UUID.randomUUID().toString().replaceAll("-", "") + ".png";
return UpYunClient.upload(fileName, bytes);
} catch (Exception e) {
LOGGER.error("create qrcode error", e);
}
return null;
}
public static byte[] createQrCode2Bytes(String text) {
return createQrCode2Bytes(DAFAULT_WIDTH, DAFAULT_HEIGHT, text);
}
public static byte[] createQrCode2Bytes(int widht, int height, String text) {
HashMap<EncodeHintType, String> hints = new HashMap<EncodeHintType, String>();
hints.put(EncodeHintType.CHARACTER_SET, "UTF-8");
try {
BitMatrix bitMatrix =
new MultiFormatWriter().encode(text, BarcodeFormat.QR_CODE, widht, height,
hints);
ByteArrayOutputStream out = new ByteArrayOutputStream();
BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);
ImageIO.write(image, "png", out);
return out.toByteArray();
} catch (Exception e) {
LOGGER.error("create qrcode error", e);
}
return null;
}
/**
* 生成條形碼并已字節(jié)碼形式返回,生成的圖片格式為png
*
* @param contents
* @param width
* @param height
* @return
*/
public static byte[] createBarcode2Byte(String contents, int width, int height) {
int codeWidth = 3 + // start guard
(7 * 6) + // left bars
5 + // middle guard
(7 * 6) + // right bars
3; // end guard
codeWidth = Math.max(codeWidth, width);
try {
BitMatrix bitMatrix =
new MultiFormatWriter().encode(contents, BarcodeFormat.CODE_128, codeWidth,
height, null);
BufferedImage image = MatrixToImageWriter.toBufferedImage(bitMatrix);
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(image, "png", out);
return out.toByteArray();
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
}
二維碼生成我這里用的是谷歌的看下面maven pom.xml 文件
<!-- 條形碼、二維碼生成 -->
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>core</artifactId>
<version>2.2</version>
</dependency>
<dependency>
<groupId>com.google.zxing</groupId>
<artifactId>javase</artifactId>
<version>2.2</version>
</dependency>
合成圖片方法如何
package com.qft.campuscircle.common.util;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import java.net.URL;
import javax.imageio.ImageIO;
import org.springframework.stereotype.Component;
@Component
public class ImageHandleUtil {
private Font font = null;
private Graphics2D g = null;
/**
* 導(dǎo)入本地圖片到緩沖區(qū)
*
* @param imgName
* @return
*/
public BufferedImage loadImageLocal(String imgName) {
try {
return ImageIO.read(new File(imgName));
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 導(dǎo)入網(wǎng)絡(luò)圖片到緩沖區(qū)
*
* @param imgName
* @return
*/
public BufferedImage loadImageUrl(String imgName) {
try {
URL url = new URL(imgName);
return ImageIO.read(url);
} catch (IOException e) {
e.printStackTrace();
}
return null;
}
/**
* 生成新圖片到本地
*
* @param newImage
* @param img
*/
public void writeImageLocal(String newImage, BufferedImage img) {
if (newImage != null && img != null) {
try {
// 目錄不存在則創(chuàng)建
String dirUrl = newImage.substring(0, newImage.lastIndexOf(File.separator));
File dir = new File(dirUrl);
if (!dir.exists()) {
dir.mkdirs();
}
File outputfile = new File(newImage);
ImageIO.write(img, "png", outputfile);
} catch (IOException e) {
e.printStackTrace();
}
}
}
/**
* 設(shè)定文字的字體等
*
* @param fontStyle
* @param fontSize
*/
public void setFont(String name, int style, int fontSize) {
this.font = new Font(name, style, fontSize);
}
/**
* 修改圖片,返回修改后的圖片緩沖區(qū)(只輸出一行文本),圖片居中顯示
*
* @param img
* @param content
* @param y
* @param color
* @return
*/
public BufferedImage modifyImage(BufferedImage img, Object content, int y, Color color) {
try {
g = img.createGraphics();
g.setBackground(Color.WHITE);
g.setColor(color);// 設(shè)置字體顏色
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 抗鋸齒
if (this.font != null)
g.setFont(this.font);
int width = img.getWidth();// 圖片寬度
if (content != null) {
String str = content.toString();
int strWidth = g.getFontMetrics().stringWidth(str);// 字體寬度
g.drawString(str, (width - strWidth) / 2, y);
}
g.dispose();
} catch (Exception e) {
e.printStackTrace();
}
return img;
}
public BufferedImage modifyImage(BufferedImage img, Object content, int x, int y, Color color) {
try {
g = img.createGraphics();
g.setBackground(Color.WHITE);
g.setColor(color);// 設(shè)置字體顏色
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);// 抗鋸齒
if (this.font != null)
g.setFont(this.font);
if (content != null) {
String str = content.toString();
g.drawString(str, x, y);
}
g.dispose();
} catch (Exception e) {
e.printStackTrace();
}
return img;
}
/**
* 將一張圖片畫在另一張圖片上
*
* @param addImage 被添加的圖片
* @param sourceImg 源圖
* @param x
* @param y
* @param width
* @param height
* @return
*/
public BufferedImage modifyImagetogeter(BufferedImage addImage, BufferedImage sourceImg, int x,
int y) {
int width = addImage.getWidth();
int height = addImage.getHeight();
try {
g = sourceImg.createGraphics();
g.drawImage(addImage, x, y, width, height, null);
g.dispose();
} catch (Exception e) {
e.printStackTrace();
}
return sourceImg;
}
/**
*
* @param img1
* @param img2
* @param title 標(biāo)題
* @param reservePrice 現(xiàn)價
* @param zkFinalPrice 折扣價
* @return BufferedImage
* @throws IOException
*/
public BufferedImage mergeImage(BufferedImage img1, BufferedImage img2,String title,String reservePrice,String zkFinalPrice)
throws IOException {
Font font = new Font("微軟雅黑", Font.BOLD, 20);
int w1 = img1.getWidth();
int h1 = img1.getHeight();
int w2 = img2.getWidth();
int h2 = img2.getHeight();
BufferedImage newImage = new BufferedImage(w1, h2 + h1 + h2/2, BufferedImage.TYPE_INT_RGB);// 新的圖
Graphics2D graphics = (Graphics2D) newImage.getGraphics();
graphics.setBackground(Color.WHITE);
graphics.fillRect(0, 0, newImage.getWidth(), newImage.getHeight());
graphics.drawImage(img1, 0, 0, null);
graphics.drawImage(img2, (newImage.getWidth()) / 2 - (w2 / 2), newImage.getHeight() - h2,
null);
graphics.setFont(font);
graphics.setColor(Color.BLACK);
int width = graphics.getFontMetrics(font).stringWidth(title);
int startY = h1 + 30;
if (width > newImage.getWidth()) {
char[] array = title.toCharArray();
StringBuilder sb = new StringBuilder(array[0]);
for (char c : array) {
sb.append(c);
int newWidth = graphics.getFontMetrics(font).stringWidth(sb.toString());
if ((newWidth + 19) >= newImage.getWidth()) {// 準(zhǔn)備換行
graphics.drawString(sb.toString(), 0, startY);
startY += 30;
sb.delete(0, sb.length());
}
}
graphics.drawString(sb.toString(), 0, startY);
} else {
graphics.drawString(title, 0, startY);
}
graphics.drawString("現(xiàn)價¥"+reservePrice, 0, startY + 30);
startY += 30;
graphics.drawString("卷后價¥"+zkFinalPrice, 0, startY + 30);
return newImage;
}
}
兩個幫助類里面有很多方法沒用到,大家只要看幾個關(guān)鍵的方法就可以了,TaoBaoQRCode 對象里面的屬性我就沒列出來了,大家自己根據(jù)自己的需求而定
以上就是java 實(shí)現(xiàn)圖片合成,并添加文字的詳細(xì)內(nèi)容,更多關(guān)于Java 圖片合成的資料請關(guān)注腳本之家其它相關(guān)文章!
相關(guān)文章
springboot驗(yàn)證碼的生成與驗(yàn)證的兩種方法
本文主要介紹了springboot驗(yàn)證碼的生成與驗(yàn)證的兩種方法,文中通過示例代碼介紹的非常詳細(xì),對大家的學(xué)習(xí)或者工作具有一定的參考學(xué)習(xí)價值,需要的朋友們下面隨著小編來一起學(xué)習(xí)學(xué)習(xí)吧2022-06-06
Java判斷中英文符號、標(biāo)點(diǎn)的實(shí)現(xiàn)
本篇文章主要介紹了Java判斷中英文符號、標(biāo)點(diǎn)的實(shí)現(xiàn),小編覺得挺不錯的,現(xiàn)在分享給大家,也給大家做個參考。一起跟隨小編過來看看吧2017-10-10
@Async導(dǎo)致controller?404及失效原因解決分析
這篇文章主要為大家介紹了@Async導(dǎo)致controller?404失效問題解決,有需要的朋友可以借鑒參考下,希望能夠有所幫助,祝大家多多進(jìn)步,早日升職加薪2022-07-07
Java文件上傳與文件下載實(shí)現(xiàn)方法詳解
這篇文章主要介紹了Java文件上傳與文件下載實(shí)現(xiàn)方法,結(jié)合實(shí)例形式詳細(xì)分析了Java文件上傳與文件下載相關(guān)操作原理、實(shí)現(xiàn)方法及相關(guān)操作注意事項(xiàng),需要的朋友可以參考下2019-02-02

