java創建透明背景的PNG圖片加自定義文字水印


    人在碼上走,需求天天有。這不,今天前端讓我返回一個帶自定義水印的背景圖片。一通google,有現成的代碼,但是基本是直接在源圖上添加水印,生成出來的文字樣式也沒有控制好,看來又只有自己造輪子了。

   過程有點曲折,直接上最終代碼:

import java.awt.AlphaComposite;
import java.awt.Color;
import java.awt.Font;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;


/**
 * 圖片處理工具類 基於https://blog.csdn.net/beinlife/article/details/53665152 改造
 */
public class ImageUtil {


    /**
     * 生成背景透明的 文字水印,文字位於透明區域正中央,可設置旋轉角度
     *
     * @param width 生成圖片寬度
     * @param heigth 生成圖片高度
     * @param text 水印文字
     * @param color 顏色對象
     * @param font awt字體
     * @param degree 水印文字旋轉角度
     * @param alpha 水印不透明度0f-1.0f
     */
    public static BufferedImage waterMarkByText(int width, int heigth, String text, Color color,
            Font font, Double degree, float alpha) {
        BufferedImage buffImg = new BufferedImage(width, heigth, BufferedImage.TYPE_INT_RGB);
        /**2、得到畫筆對象*/
        Graphics2D g2d = buffImg.createGraphics();
        // ----------  增加下面的代碼使得背景透明  -----------------
        buffImg = g2d.getDeviceConfiguration()
                .createCompatibleImage(width, heigth, Transparency.TRANSLUCENT);
        g2d.dispose();
        g2d = buffImg.createGraphics();
        // ----------  背景透明代碼結束  -----------------

        // 設置對線段的鋸齒狀邊緣處理
        g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
                RenderingHints.VALUE_INTERPOLATION_BILINEAR);

        //把源圖片寫入
//            g2d.drawImage(srcImg.getScaledInstance(srcImg.getWidth(null),
//                    srcImg.getHeight(null), Image.SCALE_SMOOTH), 0, 0,null);

        // 設置水印旋轉
        if (null != degree) {
            //注意rotate函數參數theta,為弧度制,故需用Math.toRadians轉換一下
            //以矩形區域中央為圓心旋轉
            g2d.rotate(Math.toRadians(degree), (double) buffImg.getWidth() / 2,
                    (double) buffImg.getHeight() / 2);
        }

        // 設置顏色
        g2d.setColor(color);

        // 設置 Font
        g2d.setFont(font);

        //設置透明度:1.0f為透明度 ,值從0-1.0,依次變得不透明
        g2d.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
        //獲取真實寬度
        float realWidth = getRealFontWidth(text);
        float fontSize = font.getSize();
        //計算繪圖偏移x、y,使得使得水印文字在圖片中居中
        //這里需要理解x、y坐標是基於Graphics2D.rotate過后的坐標系
        float x = 0.5f * width - 0.5f * fontSize * realWidth;
        float y = 0.5f * heigth + 0.5f * fontSize;
        //取繪制的字串寬度、高度中間點進行偏移,使得文字在圖片坐標中居中
        g2d.drawString(text, x, y);
        //釋放資源
        g2d.dispose();
//        System.out.println("添加水印文字完成!");
        return buffImg;

    }
    public static BufferedImage waterMarkByText(int width, int heigth, String text, Color color, float alpha) {
        //jdk默認字體
        Font font = new Font("Dialog", Font.ROMAN_BASELINE, 33);
        return waterMarkByText(width, heigth, text, color,font, -30d, alpha);
    }
    public static BufferedImage waterMarkByText(int width, int heigth, String text, float alpha) {
        return waterMarkByText(width, heigth, text, Color.GRAY, alpha);
    }


    public static BufferedImage waterMarkByText(int width, int heigth, String text) {
        return waterMarkByText(width, heigth, text, 0.2f);
    }

    public static BufferedImage waterMarkByText(String text) {
        return waterMarkByText(200, 150, text);
    }

    /**
     * 獲取真實字符串寬度,ascii字符占用0.5,中文字符占用1.0
     */
    private static float getRealFontWidth(String text) {
        int len = text.length();
        float width = 0f;
        for (int i = 0; i < len; i++) {
            if (text.charAt(i) < 256) {
                width += 0.5f;
            } else {
                width += 1.0f;
            }
        }
        return width;
    }


    public static void main(String[] args) {
        int width = 200;
        int heigth = 150;
        Font font = new Font("微軟雅黑", Font.ROMAN_BASELINE, 33);//字體
        BufferedImage bi1 = waterMarkByText(width, heigth, "測試aB~,", Color.GRAY, font, -30d,
                0.2f);//給圖片添加文字水印
//        BufferedImage bi = waterMarkByText(width, heigth, "測試aB~,", Color.GRAY, -30d,
//                0.2f);//給圖片添加文字水印
//        BufferedImage bi2 = waterMarkByText(width, heigth, "測試aB~,");//給圖片添加文字水印
//        BufferedImage bi3 = waterMarkByText("測試aB~,");
        try {
            ImageIO.write(bi1, "png", new File("D:/test.png"));//寫入文件
            System.out.println(Color.decode("#00bcd4"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

最終效果如下:

 

完美解決~


免責聲明!

本站轉載的文章為個人學習借鑒使用,本站對版權不負任何法律責任。如果侵犯了您的隱私權益,請聯系本站郵箱yoyou2525@163.com刪除。



 
粵ICP備18138465號   © 2018-2025 CODEPRJ.COM