話不多說,直接上成品
原底圖
開始:入口:get()
package com.ruoyi.web.controller.picture;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.utils.ImagEyeCopyHelper;
import com.ruoyi.common.utils.ImageUtils;
import com.ruoyi.system.service.IPictureService;
import io.swagger.annotations.Api;
import io.swagger.annotations.ApiOperation;
import org.springframework.beans.factory.annotation.Autowired;
import org.springframework.web.bind.annotation.PostMapping;
import org.springframework.web.bind.annotation.RequestMapping;
import org.springframework.web.bind.annotation.RestController;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.BufferedOutputStream;
import java.io.File;
import java.io.FileOutputStream;
@Api(description = "圖檔生成控制器")
@RestController
@RequestMapping("/picture")
public class PictureController {
@Autowired
private IPictureService iPictureService;
@ApiOperation("生成圖檔")
@PostMapping("/generate")
public R generate() throws Exception{
return R.ok(iPictureService.generate());
}
public static void main(String[] args) throws Exception {
System.out.println(get());
}
public static String get() throws Exception {
String imageUrl = "";
final BufferedImage thumbImage = ImagEyeCopyHelper.getBaseImage(imageUrl);
// 先添加平鋪式水印
ImageUtils.addWaterMark(thumbImage, "@是我小湯圓呀");
// 添加文字内容填充
Font font = new Font("微軟雅黑", Font.PLAIN, 45);
Color red = new Color(255, 200, 0,255);
Color black = new Color(0, 0, 0, 255);
ImageUtils.addWaterMark(thumbImage, "大風吹倒梧桐樹,自有旁人論短長。", red, font, 180, 320);
ImageUtils.addWaterMark(thumbImage, "針對同一件事,不同的人站在不同的角度,", black, font, 180, 510);
ImageUtils.addWaterMark(thumbImage, "會有不同的看法。任何事情都有評論,不要", black , font, 180, 610);
ImageUtils.addWaterMark(thumbImage, "太計較别人的看法,太計較别人的看法不是", black, font, 180, 710);
ImageUtils.addWaterMark(thumbImage, "一件好事,會迷失自我。", black, font, 180, 810);
ImageUtils.addWaterMark(thumbImage, "2022年10月26日", black, font, 700, 910);
ImageUtils.addWaterMark(thumbImage, "@是我小湯圓呀", black, font, 710, 1010);
// 寫到本地
String path = "D:\\" + System.currentTimeMillis() + ".jpg";
BufferedOutputStream out = new BufferedOutputStream(new FileOutputStream(path));
String formatName = path.substring(path.lastIndexOf(".") + 1);
System.out.println("formatName is :" + formatName);
ImageIO.write(thumbImage, formatName, new File(path));
out.close();
return null;
}
}
ImagEyeCopyHelper.java
package com.ruoyi.common.utils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.io.InputStream;
public class ImagEyeCopyHelper {
/**
* left代表圖檔距離畫布最左端的距離
*/
private static final int left = 1320;
/**
* top代表圖檔距離畫布最上端的距離
*/
private static final int top = 80;
/**
* 擷取一張基礎的圖檔素材底圖
*
* @param userImagUrl 網絡圖檔位址
* @return
* @throws IOException
*/
public static BufferedImage getBaseImage(String userImagUrl) throws IOException {
// 加載本地基礎底圖圖檔
InputStream inputStream = ImagEyeCopyHelper.class.getClassLoader().getResourceAsStream("picture/bg-clean-01.jpg");
BufferedImage thumbImage = ImageIO.read(inputStream);
Graphics2D g = thumbImage.createGraphics();
if (StringUtils.isEmpty(userImagUrl)) {
return thumbImage;
}
BufferedImage minImag = ImageUtils.getUrlByBufferedImage(userImagUrl);
// 先裁切成圓形
minImag = ImageUtils.convertCircular(minImag);
// 圖檔合成
g.drawImage(minImag.getScaledInstance(160, 160, Image.SCALE_SMOOTH), left, top, null);
return thumbImage;
}
}
ImageUtils.java
package com.ruoyi.common.utils;
import javax.imageio.ImageIO;
import java.awt.*;
import java.awt.font.FontRenderContext;
import java.awt.font.TextLayout;
import java.awt.geom.AffineTransform;
import java.awt.geom.Ellipse2D;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.HttpURLConnection;
import java.net.URL;
public class ImageUtils {
/**
* 通過網絡擷取圖檔
*
* @param url
* @return
*/
public static BufferedImage getUrlByBufferedImage(String url) {
try {
URL urlObj = new URL(url);
HttpURLConnection conn = (HttpURLConnection) urlObj.openConnection();
// 連接配接逾時
conn.setDoInput(true);
conn.setDoOutput(true);
conn.setConnectTimeout(25000);
// 讀取逾時 --伺服器響應比較慢,增大時間
conn.setReadTimeout(25000);
conn.setRequestMethod("GET");
conn.addRequestProperty("Accept-Language", "zh-cn");
conn.addRequestProperty("Content-type", "image/jpeg");
conn.addRequestProperty("User-Agent", "Mozilla/4.0 (compatible; MSIE 8.0; Windows NT 5.1; Trident/4.0; .NET CLR 2.0.50727)");
conn.connect();
BufferedImage bufImg = ImageIO.read(conn.getInputStream());
conn.disconnect();
return bufImg;
} catch (Exception e) {
e.printStackTrace();
}
return null;
}
/**
* 傳入的圖像必須是正方形的 才會 圓形 如果是長方形的比例則會變成橢圓的
*
* @param image 使用者頭像
* @return
* @throws IOException
*/
public static BufferedImage convertCircular(BufferedImage image) throws IOException {
int min;//若是長方形圖檔則按照邊短的去裁剪成圓,如果沒有這個就會變成橢圓
if (image.getWidth() > image.getHeight()) {
min = image.getHeight();
} else {
min = image.getWidth();
}
// 透明底的圖檔
BufferedImage bi2 = new BufferedImage(min, min, BufferedImage.TYPE_4BYTE_ABGR);
Ellipse2D.Double shape = new Ellipse2D.Double(0, 0, min, min);
Graphics2D g2 = bi2.createGraphics();
g2.setClip(shape);
// 使用 setRenderingHint 設定抗鋸齒
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.drawImage(image, 0, 0, null);
// 設定顔色
g2.setBackground(Color.green);
g2.dispose();
return bi2;
}
/**
* 對圖檔上添加平鋪式水印
*
* @param image
* @param text
* @throws IOException
*/
public static void addWaterMark(BufferedImage image, String text) {
if (StringUtils.isEmpty(text)) {
return;
}
int angel = -30;//旋轉角度
int xpadding = 400;//每個水印水準間隔
int ypadding = 400;//每個水印垂直間隔
int fontSize = 22;
Graphics2D g = image.createGraphics();
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
//繪制原圖檔
float alpha = 1F;
AlphaComposite ac = AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha);
g.setComposite(ac);
g.drawImage(image, 0, 0, image.getWidth(), image.getHeight(), null);
g.setBackground(Color.BLACK);
//開始繪制水印
//水印字型
Font font = new Font("微軟雅黑", Font.BOLD, fontSize);
g.setFont(font);
FontRenderContext frc = g.getFontRenderContext();
TextLayout tl = new TextLayout(text, font, frc);
//水印串寬度
int stringWidth = g.getFontMetrics(g.getFont()).charsWidth(text.toCharArray(), 0, text.length());
//旋轉水印
g.rotate(Math.toRadians(angel), (double) image.getWidth() / 2, (double) image.getHeight() / 2);
//水印透明度
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 0.1F));
// 字型色
g.setColor(Color.black);
int x = -image.getHeight() / 2;
int y = -image.getWidth() / 2;
//循環繪制
while (x < image.getWidth() + image.getHeight() / 2) {
y = -image.getWidth() / 2;
while (y < image.getHeight() + image.getWidth() / 2) {
Shape sha = tl.getOutline(AffineTransform.getTranslateInstance(x, y));
g.fill(sha);
y += ypadding;
}
x += stringWidth + xpadding;
}
//釋放資源
g.dispose();
}
/**
* 對圖檔上添加文字 普通文字
*
* @param bufImg 源圖檔
* @param waterMarkContent 文字内容
* @param markContentColor 文字顔色
* @param font 文字字型
* @param x 坐标 左上角為起點
* @param y 坐标 左上角為起點
*/
public static void addWaterMark(BufferedImage bufImg, String waterMarkContent, Color markContentColor, Font font, int x, int y) {
try {
// 加水印
Graphics2D g = bufImg.createGraphics();
g.drawImage(bufImg, 0, 0, bufImg.getWidth(), bufImg.getHeight(), null);
g.setColor(markContentColor); //根據圖檔的背景設定水印顔色
g.setFont(font); //設定字型
//設定水印的坐标
g.drawString(waterMarkContent, x, y); //畫出水印
g.dispose();
} catch (Exception e) {
e.printStackTrace();
}
}
}
搞掂收工!
純屬抄書,有錯提出,勿噴。