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

Java 2D 進階繪圖:實現發光邊框與投影效果的核心技術

     編輯:Java 相關知識

視覺效果對比

左側為普通扁平圖形,右側應用漸變填充、抗鋸齒、發光邊框、投影後的立體效果:

普通 vs 增強圖形

最終效果含投影

核心技術拆解

1. 軟裁剪:BufferedImage + AlphaComposite

創建半透明兼容圖像,啟用抗鋸齒,繪製白色形狀作為 Alpha 遮罩:

GraphicsConfiguration gc = g.getDeviceConfiguration();
BufferedImage img = gc.createCompatibleImage(w, h, Transparency.TRANSLUCENT);
Graphics2D g2 = img.createGraphics();
g2.setComposite(AlphaComposite.Clear);
g2.fillRect(0, 0, w, h);
g2.setComposite(AlphaComposite.Src);
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setColor(Color.WHITE);
g2.fill(shape);  // 形狀變為 Alpha=1 的區域,其餘 Alpha=0
g2.dispose();
return img;  // 作為軟裁剪遮罩

2. 漸變填充:GradientPaint

在裁剪圖像上繪製垂直漸變:

g2.setPaint(new GradientPaint(0, 0, clrHi, 0, height, clrLo));
g2.fill(clipShape);

3. 發光邊框:多層描邊 + SRC_ATOP 合成

核心技巧:從粗到細描邊,顏色從內發光色漸變至外發光色,透明度逐漸增加,配合 SRC_ATOP 僅保留形狀內部區域:

private void paintBorderGlow(Graphics2D g2, int glowWidth) {
    int gw = glowWidth * 2;
    for (int i = gw; i >= 2; i -= 2) {
        float pct = (float)(gw - i) / (gw - 1);  // 0→1
        Color mixHi = mixColor(clrGlowInnerHi, pct, clrGlowOuterHi, 1-pct);
        Color mixLo = mixColor(clrGlowInnerLo, pct, clrGlowOuterLo, 1-pct);
        g2.setPaint(new GradientPaint(0, height*0.25f, mixHi, 0, height, mixLo));
        g2.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_ATOP, pct));
        g2.setStroke(new BasicStroke(i));
        g2.draw(clipShape);  // 裁剪確保僅內部可見
    }
}

mixColor() 線性插值 RGBA 分量實現顏色漸變。

4. 投影效果:同理繪製外部灰色邊框

private void paintBorderShadow(Graphics2D g2, int shadowWidth) {
    g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
    int sw = shadowWidth * 2;
    for (int i = sw; i >= 2; i -= 2) {
        float pct = (float)(sw - i) / (sw - 1);
        g2.setColor(mixColor(Color.LIGHT_GRAY, pct, Color.WHITE, 1-pct));
        g2.setStroke(new BasicStroke(i));
        g2.draw(clipShape);  // 無 SRC_ATOP,繪製在形狀外部
    }
}

調用順序:先 paintBorderShadow(外部陰影)→ 再填充漸變 → 最後 paintBorderGlow(內部發光)。

完整繪製流程

// 1. 創建形狀(圓角矩形+貝塞爾曲線)
Shape clipShape = createClipShape();

// 2. 創建軟裁剪遮罩
BufferedImage clipImage = createClipImage(clipShape);
Graphics2D g2 = clipImage.createGraphics();

// 3. 繪製陰影(最外層)
paintBorderShadow(g2, 6);

// 4. 漸變填充形狀主體
g2.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g2.setComposite(AlphaComposite.SrcAtop);
g2.setPaint(new GradientPaint(0, 0, clrHi, 0, height, clrLo));
g2.fill(clipShape);

// 5. 繪製發光邊框(內層)
paintBorderGlow(g2, 8);

g2.dispose();

// 6. 將最終圖像繪製到屏幕
g.drawImage(clipImage, 0, 0, null);

關鍵 API 總結

API作用
AlphaComposite.SRC_ATOP僅在目標非透明區域顯示源圖像(實現內部發光裁剪)
GradientPaint線性漸變填充
BasicStroke控制描邊寬度
RenderingHints.VALUE_ANTIALIAS_ON抗鋸齒,邊緣平滑
BufferedImage.TYPE_TRANSLUCENT支持 Alpha 通道的離屏圖像

擴展建議

  • 使用 RadialGradientPaint 實現點光源效果
  • 結合 DropShadowFilter (SwingX) 簡化陰影實現
  • 性能敏感場景緩存 BufferedImage 避免重繪
  • JavaFX 內置 DropShadow, Glow 效果更簡潔

總結

Java 2D 通過離屏圖像、Alpha 合成、漸變描邊疊加,能實現媲美專業設計軟件的視覺效果。掌握 SRC_ATOP 裁剪技巧與多層描邊漸變,是打造高質量 UI 的關鍵。建議在自定義組件 paintComponent() 中封裝此邏輯,構建可復用的視覺組件庫。

  1. 上一篇文章:
  2. 下一篇文章:
Copyright © 程式碼之家 All Rights Reserved