天天看點

java 圖檔添加水印、文字

作者:小湯圓和大明

話不多說,直接上成品

java 圖檔添加水印、文字

原底圖

java 圖檔添加水印、文字

開始:入口: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();
        }
    }
}
           

搞掂收工!

純屬抄書,有錯提出,勿噴。