首頁 > 軟體

Java實現新增文字水印&圖片水印的方法詳解

2023-11-01 18:00:51

為什麼要給圖片新增水印

為圖片新增水印的主要作用是保護圖片版權,防止圖片被未經授權的人使用或傳播。

通常情況下,圖片水印會包含圖片作者的名字、版權資訊或公司商標等資訊,這些資訊可以幫助識別圖片的所有者,並對未經授權的使用進行追究

此外,圖片水印還可以用於提醒人們圖片的使用限制,例如是否需要授權、是否可以用於商業用途等。

除此之外,圖片水印還可以用於增加圖片的視覺吸引力或宣傳性,例如可以在圖片中新增品牌 logo 或宣傳標語等。

總的來說,圖片水印的主要作用是保護圖片版權和提醒人們圖片的使用限制,但也可以用於提升圖片的視覺效果和宣傳性。

繪製文字水印

為圖片新增水印是一種常用的圖片處理技術。在 Java 中可以使用 Graphics2D 類來繪製水印。

以下是一個簡單的例子,展示瞭如何在圖片的右下角新增一個水印:

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

public class Watermark {
    public static void main(String[] args) {
        // 讀取原圖片
        BufferedImage image = null;
        try {
            image = ImageIO.read(new File("original.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 獲取圖片的寬度和高度
        int width = image.getWidth();
        int height = image.getHeight();
        // 建立一個圖片快取物件
        BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 獲取圖片的畫筆
        Graphics2D g = newImage.createGraphics();
        // 將原圖片繪製到快取圖片上
        g.drawImage(image, 0, 0, width, height, null);
        // 設定水印的字型樣式
        g.setFont(new Font("微軟雅黑", Font.BOLD, 20));
        // 設定水印的顏色
        g.setColor(Color.red);
        // 設定水印的位置
        g.drawString("Hello World!", width - 120, height - 10);
        // 釋放圖形上下文使用的系統資源
        g.dispose();
        // 儲存帶水印的圖片
        try {
            ImageIO.write(newImage, "jpg", new File("watermarked.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

動態計算字串的寬度

如果你已經知道了字串的大小(size)和內容(str),想要計算字串的寬度,可以使用以下方法:

首先建立一個 Font 物件,使用該物件的 getStringBounds 方法計算字串的寬度。

import java.awt.Font;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;

public class StringWidth {
    public static void main(String[] args) {
        // 字串內容
        String str = "Hello World!";
        // 字型大小
        int size = 20;
        // 建立字型物件
        Font font = new Font("微軟雅黑", Font.BOLD, size);
        // 建立字型渲染上下文
        FontRenderContext frc = new FontRenderContext(null, true, true);
        // 計算字串的寬度
        Rectangle2D bounds = font.getStringBounds(str, frc);
        // 輸出字串的寬度
        System.out.println(bounds.getWidth());
    }
}

在這段程式碼中,我們首先建立了一個 Font 物件,然後使用該物件的 getStringBounds 方法計算字串的寬度。

注意,在呼叫 getStringBounds 方法時,需要傳入一個 FontRenderContext 物件,該物件用於描述字型的渲染環境,可以影響字串的顯示效果。

最後,計算出的字串寬度是一個 Rectangle2D 物件,你可以使用 getWidth 方法來獲取實際的寬度值。

自適應文字水印位置

可以看到,我們新增的水印已經超出了圖片的範圍,導致顯示不完全,出現這種結果的原因是因為我們預設字元的寬度為120px.您可以通過上面介紹的動態計算字元寬度來讓水印始終顯示在圖片上。

import java.awt.Color;
import java.awt.font.FontRenderContext;
import java.awt.geom.Rectangle2D;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class Watermark {
    public static void main(String[] args) {
        // 讀取原圖片
        BufferedImage image = null;
        try {
            image = ImageIO.read(new File("original.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 獲取圖片的寬度和高度
        int width = image.getWidth();
        int height = image.getHeight();
        // 建立一個圖片快取物件
        BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 獲取圖片的畫筆
        Graphics2D g = newImage.createGraphics();
        // 字串內容
        String str = "Hello World!";
        // 字型大小
        int size = 20;
        // 建立字型物件
        Font font = new Font("微軟雅黑", Font.BOLD, size);
        // 建立字型渲染上下文
        FontRenderContext frc = new FontRenderContext(null, true, true);
        // 計算字串的寬度和高度
        Rectangle2D bounds = font.getStringBounds(str, frc);
        // 字元寬度
        int strWidth = (int)bounds.getWidth();
        // 字元高度
        int strHeight = (int)bounds.getHeight();
        // 將原圖片繪製到快取圖片上
        g.drawImage(image, 0, 0, width, height, null);
        // 設定水印的字型樣式
        g.setFont(font);
        // 設定水印的顏色
        g.setColor(Color.red);
        // 設定水印的位置
        g.drawString("Hello World!", width - strWidth - 10, height - strHeight - 10);
        // 釋放圖形上下文使用的系統資源
        g.dispose();
        // 儲存帶水印的圖片
        try {
            ImageIO.write(newImage, "jpg", new File("watermarked.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

繪製圖片水印

如果你想在 png 格式的圖片上繪製透明的圖片水印,可以使用以下方法:

首先讀取原圖片和水印圖片,然後使用 Graphics2D 類的 drawImage 方法將水印圖片繪製到原圖片上,最後使用 setComposite 方法設定水印圖片的 alpha 通道值來調整水印的透明度。

紫色部分為圖片水印。

具體實現如下:

import java.awt.AlphaComposite;
import java.awt.Graphics2D;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;

public class TransparentWatermark {
    public static void main(String[] args) {
        // 讀取原圖片
        BufferedImage image = null;
        try {
            image = ImageIO.read(new File("original.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 獲取圖片的寬度和高度
        int width = image.getWidth();
        int height = image.getHeight();
        // 建立一個圖片快取物件
        BufferedImage newImage = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        // 獲取圖片的畫筆
        Graphics2D g = newImage.createGraphics();
        // 將原圖片繪製到快取圖片上
        g.drawImage(image, 0, 0, width, height, null);
        // 讀取水印圖片
        BufferedImage watermark = null;
        try {
            watermark = ImageIO.read(new File("watermark.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        // 獲取水印圖片的寬度和高度
        int wmWidth = watermark.getWidth();
        int wmHeight = watermark.getHeight();
        // 設定水印圖片的透明度
        g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, 0.5f));
        // 繪製水印圖片
        g.drawImage(watermark, width - wmWidth - 10, height - wmHeight - 10, wmWidth, wmHeight, null);
        // 釋放圖形上下文使用的系統資源
        g.dispose();
        // 儲存帶水印的圖片
        try {
            ImageIO.write(newImage, "png", new File("watermarked.png"));
        } catch (IOException e) {
            e.printStackTrace();
        }
    }
}

提升圖片處理速度

目前我們新增文字水印和圖片水印耗時都在 700ms - 2000ms

可以考慮以下幾種方法來提升速度:

  • 使用多執行緒:如果你需要批次新增文字水印,可以考慮使用多執行緒的方式來加速處理速度。例如,你可以將圖片分成多份,每份使用一個執行緒處理,最後再將結果合併。
  • 使用更快的圖片處理庫:如果你使用的是 Java 原生的圖片處理工具(例如 java.awt 包),可以考慮使用更快的圖片處理庫,例如 OpenCV、Imaging、Thumbnails 等。這些庫通常具有更快的處理速度,並且支援更多的圖片格式和操作。
  • 減少圖片的質量:如果你的圖片尺寸較大,可以考慮將圖片的質量壓縮到一個較低的水平,這樣可以減少圖片的體積,從而加快處理速度。
  • 優化程式碼:如果你的程式碼有一些低效的地方,可以考慮優化程式碼,提升程式的執行效率。例如,可以避免使用過多的迴圈和分支語句,或者使用更快的演演算法等。

到此這篇關於Java實現新增文字水印&圖片水印的方法詳解的文章就介紹到這了,更多相關Java新增水印內容請搜尋it145.com以前的文章或繼續瀏覽下面的相關文章希望大家以後多多支援it145.com!


IT145.com E-mail:sddin#qq.com