通過java
來繪制海報(bào)射亏,加載外部字體并設(shè)置樣式大小與加粗虫腋、設(shè)置背景圖莽红、合并圖片妥畏,下面是簡單示例
import javax.imageio.ImageIO;
import java.awt.Color;
import java.awt.Font;
import java.awt.FontMetrics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.geom.Rectangle2D;
import java.awt.image.BufferedImage;
import java.io.ByteArrayOutputStream;
import java.io.File;
import java.io.FileOutputStream;
import java.util.ArrayList;
import java.util.List;
/** java 繪制海報(bào)
* author xiaochi
* date 2024/11/8
*/
public class PosterCreatorTest{
public static void main(String[] args) throws Exception {
// 創(chuàng)建字體
// Font font = new Font("微軟雅黑", Font.BOLD, 36);
// 外部字體
String fontPath = "D:\\workspace\\demo3\\src\\main\\resources\\font\\SmileySans2.ttf";
Font font = Font.createFont(Font.TRUETYPE_FONT, new File(fontPath));
// 合并到圖片上的文字
String text = "歡迎來到我的世界";
int width = 854;// 容器寬度
int height = 1280;// 容器高度
BufferedImage bgImage = ImageIO.read(new File("D:\\workspace\\demo3\\test1111.png"));
BufferedImage combiner = combiner(width, height,null, bgImage, bgImage.getWidth(),bgImage.getHeight());
Graphics2D g2d = combiner.createGraphics();
// 繪制文本2(不換行)
g2d.setColor(getColor("#1bdf1a"));
g2d.drawString(text, 100, 100);
// 釋放圖形上下文
g2d.dispose();
// 繪制文本1(換行)
wrapText(combiner,text,font.deriveFont(Font.BOLD,26f),100,50,10,0,null);
// 設(shè)置文本旋轉(zhuǎn)45°
wrapText(combiner,text,font.deriveFont(26f),500,50,combiner.getWidth(),0,null);
wrapText(combiner,text,font.deriveFont(26f),500,50,combiner.getWidth(),45,"#ea6f5a");
// 合并圖片
BufferedImage mergeImage = ImageIO.read(new File("D:\\02.png"));
merge(combiner,mergeImage,100,100,100,500);
try {
// 保存圖片到文件
//ImageIO.write(image, "PNG", new File("D:\\workspace\\demo3\\poster.png"));
// 輸出文件流
ByteArrayOutputStream out = new ByteArrayOutputStream();
ImageIO.write(combiner,"png",out);
byte[] bytes = out.toByteArray();
out.close();
FileOutputStream fileOutputStream = new FileOutputStream("D:\\workspace\\demo3\\poster333.png");
fileOutputStream.write(bytes);
fileOutputStream.close();
} catch (Exception e) {
e.printStackTrace();
}
}
/**
* 創(chuàng)建容器
* @param combinerWidth 容器寬度
* @param combinerHeight 容器高度
* @param bgColor 背景色(默認(rèn)白色,且背景圖會覆蓋背景色)
* @param bgImage 背景圖
* @param bgImageWidth 背景圖寬度
* @param bgImageHeight 背景圖高度
* @return combiner容器
*/
public static BufferedImage combiner(int combinerWidth,int combinerHeight,String bgColor,BufferedImage bgImage,int bgImageWidth,int bgImageHeight){
BufferedImage combiner = new BufferedImage(combinerWidth,combinerHeight, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = combiner.createGraphics();
// 設(shè)置背景顏色
g2d.setColor(Color.white);
if (null != bgColor && !"".equals(bgColor)){
g2d.setColor(getColor(bgColor));
}
g2d.fillRect(0, 0, combinerWidth, combinerHeight);
// 添加背景圖片
if (null != bgImage){
// 添加背景圖片
g2d.drawImage(bgImage,0,0,bgImageWidth,bgImageHeight,null);
}
// 釋放圖形上下文
g2d.dispose();
return combiner;
}
/**
* 合并圖片
* @param combiner 容器
* @param mergeImage 待合并的圖片
* @param width 待合并的圖片寬度
* @param height 待合并的圖片高度
* @param x 待合并的圖片x坐標(biāo)
* @param y 待合并的圖片y坐標(biāo)
*/
public static void merge(BufferedImage combiner,BufferedImage mergeImage,int width,int height,int x,int y){
//BufferedImage image = new BufferedImage(100,100,BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = combiner.createGraphics();
g2d.drawImage(mergeImage,x,y,width,height,null);
g2d.dispose();
}
/**
* 繪制文字
* @param combiner 容器
* @param text 文字
* @param font 字體(包括大小、樣式安吁、顏色)
* @param x 文字x坐標(biāo)
* @param y 文字y坐標(biāo)
* @param maxWidth 文字最大寬度(0為豎排顯示)
* @param rotate 旋轉(zhuǎn)度數(shù)
* @param color 文字顏色(如:#ffffff)
*/
public static void wrapText(BufferedImage combiner,String text,Font font,int x,int y,int maxWidth,double rotate,String color){
Graphics2D g2d = combiner.createGraphics();
//設(shè)置字體
g2d.setFont(font);
// 設(shè)置文字顏色
if (null != color && !"".equals(color)){
g2d.setColor(getColor(color));
}
// 抗鋸齒屬性
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON); //提升觀感
// 設(shè)置旋轉(zhuǎn)
AffineTransform at = new AffineTransform();
at.rotate(Math.toRadians(rotate),x,y); // 旋轉(zhuǎn)45度醉蚁,旋轉(zhuǎn)中心為(文字x坐標(biāo),100)
g2d.setTransform(at);
FontMetrics fontMetrics = g2d.getFontMetrics(font);
String[] lines = splitText(text, maxWidth, fontMetrics); //實(shí)現(xiàn)文字自動(dòng)換行
int lineHeight = g2d.getFontMetrics().getHeight();
int ystart = y;
for (String line : lines) {
g2d.drawString(line, x, ystart);
ystart += lineHeight;
}
g2d.dispose();
}
/**
* 獲取顏色
* @param color #2395439
* @return
*/
public static Color getColor(String color) {
if (color.charAt(0) == '#') {
color = color.substring(1);
}
if (color.length() != 6) {
return null;
}
try {
int r = Integer.parseInt(color.substring(0, 2), 16);
int g = Integer.parseInt(color.substring(2, 4), 16);
int b = Integer.parseInt(color.substring(4), 16);
return new Color(r, g, b);
} catch (NumberFormatException nfe) {
return null;
}
}
/**
* 切割文字
* @param text
* @param maxWidth
* @param fontMetrics
* @return
*/
private static String[] splitText(String text, int maxWidth, FontMetrics fontMetrics) {
StringBuilder wrappedText = new StringBuilder();
String[] words = text.split(""); //以每個(gè)字符做拆分,可根據(jù)實(shí)際需求做更改鬼店,下同
List<String> lines = new ArrayList<>();
for (String word : words) {
// 檢查添加新單詞后是否會超過最大寬度
if (wrappedText.length() > 0) {
// 檢查加上新單詞后的總長度
if (fontMetrics.stringWidth(wrappedText.toString() + word) > maxWidth) {
// 如果超過最大寬度网棍,將當(dāng)前字符串添加到行列表,并開始新的一行
lines.add(wrappedText.toString());
wrappedText = new StringBuilder(word);
} else {
// 如果不超過最大寬度妇智,添加新單詞
wrappedText.append(word);
}
} else {
wrappedText.append(word);
}
}
// 添加最后一行
if (wrappedText.length() > 0) {
lines.add(wrappedText.toString());
}
// 將行列表轉(zhuǎn)換為數(shù)組
return lines.toArray(new String[0]);
}
}
OK了滥玷。