首頁
編程語言
C語言|JAVA編程
Python編程
網頁編程
ASP編程|PHP編程
JSP編程
數據庫
MYSQL數據庫|SqlServer數據庫
Oracle數據庫|DB2數據庫
您现在的位置: 程式碼之家 >> 編程語言 >  >> Java 程式設計 >> Java 相關知識

Java 圖片生成器實作:支援水印、干擾線與多種輸出格式

     編輯:Java 相關知識

專案概覽

本元件提供完整的圖片動態生成能力,適用於驗證碼、報表圖表、水印圖片等場景。核心特性包含:

  • 彈性設定畫布尺寸、邊框色、背景色
  • 字體大小、字型、顏色完整可配置
  • 支援 JPEG、GIF、PNG 等主流輸出格式
  • 可輸出至檔案或 OutputStream(適合 Web 直接串流回應)
  • 內建干擾線產生器,強化驗證碼防識別能力
  • 文字自動換行排版
  • 採用模板方法模式,擴充繪製邏輯極為容易

架構設計:抽象基類 AbstractImageCreator

定義圖片生成的標準流程(模板方法),將「繪製文字」與「儲存圖片」延遲至子類實作:

public abstract class AbstractImageCreator {
    private static final Random RND = new Random(System.currentTimeMillis());
    
    // 可配置屬性(省略 getter/setter)
    private int width = 200, height = 80;
    private Color rectColor, bgColor;
    private int lineNum = 0;
    private String formatName = "JPEG";
    private Color fontColor = Color.BLACK;
    private String fontName = "宋體";
    private int fontSize = 15;

    // 模板方法:定義生成骨架
    public final void drawImage(String text) throws IOException {
        BufferedImage image = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
        Graphics2D g = image.createGraphics();
        
        // 1. 背景與邊框
        g.setColor(bgColor != null ? bgColor : new Color(240, 251, 200));
        g.fillRect(0, 0, width, height);
        g.setColor(rectColor != null ? rectColor : Color.BLACK);
        g.drawRect(0, 0, width - 1, height - 1);
        
        // 2. 干擾線
        drawRandomLine(g);
        
        // 3. 繪製文字(由子類實作)
        drawString(g, text);
        
        // 4. 輸出(由子類實作)
        saveImage(image);
        g.dispose();
    }

    private void drawRandomLine(Graphics2D g) {
        for (int i = 0; i < lineNum; i++) {
            g.setColor(getRandomColor(100, 155));
            int x1 = RND.nextInt(width), y1 = RND.nextInt(height);
            int x2 = RND.nextInt(width), y2 = RND.nextInt(height);
            g.drawLine(x1, y1, x2, y2);
        }
    }
    
    private Color getRandomColor(int base, int range) {
        range = Math.min(range, 255 - base);
        return new Color(base + RND.nextInt(range), 
                         base + RND.nextInt(range), 
                         base + RND.nextInt(range));
    }

    // 留給子類實作的抽象方法
    protected abstract void drawString(Graphics2D g, String text);
    protected abstract void saveImage(BufferedImage image) throws IOException;
}

具體實作類別

1. 儲存至檔案:DefaultImageCreator

public class DefaultImageCreator extends AbstractImageCreator {
    private String outputFilePath;
    // getter/setter 省略
    
    @Override
    protected void drawString(Graphics2D g, String text) {
        g.setColor(getFontColor());
        Font font = new Font(getFontName(), Font.PLAIN, getFontSize());
        g.setFont(font);
        FontMetrics fm = g.getFontMetrics();
        int lineHeight = fm.getHeight();
        int x = 0, line = 1;
        
        for (char c : text.toCharArray()) {
            if (Character.isISOControl(c) || x >= getWidth() - fm.charWidth(c)) {
                line++; x = 0; // 自動換行
            }
            g.drawString(String.valueOf(c), x, line * lineHeight);
            x += fm.charWidth(c);
        }
    }
    
    @Override
    protected void saveImage(BufferedImage img) throws IOException {
        ImageIO.write(img, getFormatName(), new File(outputFilePath));
    }
}

2. 輸出至串流:OutputStreamImageCreator

public class OutputStreamImageCreator extends DefaultImageCreator {
    private OutputStream out;
    // getter/setter 省略
    
    @Override
    protected void saveImage(BufferedImage img) throws IOException {
        if (out != null) ImageIO.write(img, getFormatName(), out);
    }
}

使用範例

// 產生含干擾線的驗證碼圖片並寫入檔案
StringBuilder sb = new StringBuilder();
sb.append("中華人民共和國\n").append("中華人民共和國\n");

DefaultImageCreator creator = new DefaultImageCreator("c:/captcha.jpg");
creator.setWidth(150);
creator.setHeight(100);
creator.setLineNum(60);        // 60 條干擾線
creator.setFontSize(20);
creator.drawImage(sb.toString());

// Web 環境直接輸出到響應串流
// OutputStreamImageCreator creator = new OutputStreamImageCreator(response.getOutputStream());
// creator.drawImage("隨機驗證碼");

擴充建議

  • 引入 Substance 或 Java2D 進階渲染提升視覺品質
  • 整合 Google Guava Cache 快取常用字型測量結果
  • 支援 Base64 編碼輸出,便於前端 <img src="data:image/jpeg;base64,..."> 直接嵌入
  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved