Java 2D Graphics2D.scale() 方法可對繪圖座標系進行縮放,配合 translate() 實現圖像任意位置、任意倍數的放大縮小。本文演示加載 PNG 圖標並在面板上以原始尺寸、2倍放大、1/4縮小三種形式繪製的完整示例。

scale(sx, sy) 縮放座標系,後續繪製坐標自動按比例變換translate(x, y) 移動原點,控制縮放後的繪製位置scale(2.0) 再 scale(0.25) 等效於 scale(0.5)RenderingHints 提升縮放質量
import java.awt.Color;
import java.awt.Dimension;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.RenderingHints;
import javax.swing.ImageIcon;
import javax.swing.JFrame;
import javax.swing.JPanel;
public class Scale {
public static void main(String[] args) {
JFrame jf = new JFrame("Java 2D 圖像縮放");
jf.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
jf.getContentPane().add(new ScalePanel());
jf.setPreferredSize(new Dimension(500, 400));
jf.pack();
jf.setLocationRelativeTo(null);
jf.setVisible(true);
}
}
class ScalePanel extends JPanel {
@Override
protected void paintComponent(Graphics g) {
int width = getWidth();
int height = getHeight();
super.paintComponent(g);
Graphics2D g2d = (Graphics2D) g;
// 背景
g2d.setColor(Color.WHITE);
g2d.fillRect(0, 0, width, height);
g2d.setColor(Color.BLACK);
// 關鍵:開啟高質量渲染提示
g2d.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS,
RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g2d.setRenderingHint(RenderingHints.KEY_RENDERING,
RenderingHints.VALUE_RENDER_QUALITY);
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.setRenderingHint(RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
ImageIcon logoPNG;
try {
// 從 classpath 加載圖片
logoPNG = new ImageIcon(getClass().getResource("logo.png"));
// 1. 原始尺寸繪製 (10, 50)
logoPNG.paintIcon(this, g2d, 10, 50);
// 2. 放大 2 倍繪製
g2d.translate(width / 5, height / 2.5); // 移動原點
g2d.scale(2.0, 2.0); // 座標系放大 2 倍
logoPNG.paintIcon(this, g2d, 0, 0); // 在新座標系 (0,0) 繪製
// 3. 縮小到 1/4 繪製
g2d.scale(0.25, 0.25); // 累積縮放:2.0 * 0.25 = 0.5
logoPNG.paintIcon(this, g2d, 250, -180); // 注意座標在縮放後座標系中
} catch (Exception e) {
e.printStackTrace();
g2d.drawString("讀入圖像文件錯誤!", 100, 200);
}
}
}
| 提示鍵 | 推薦值 | 作用 |
|---|---|---|
| KEY_INTERPOLATION | VALUE_INTERPOLATION_BILINEAR / BICUBIC | 雙線性/雙三次插值,縮放平滑 |
| KEY_RENDERING | VALUE_RENDER_QUALITY | 優先質量而非速度 |
| KEY_ANTIALIASING | VALUE_ANTIALIAS_ON | 抗鋸齒 |
| KEY_FRACTIONALMETRICS | VALUE_FRACTIONALMETRICS_ON | 字體度量使用浮點精度 |
// 初始座標系 g2d.translate(100, 100); // 原點移至 (100,100) g2d.scale(2.0, 2.0); // 座標系放大 2 倍 g2d.drawRect(0, 0, 50, 50); // 實際繪製在 (100,100) 到 (200,200) 區域 g2d.scale(0.5, 0.5); // 累積縮放:2.0 * 0.5 = 1.0 (恢復原始比例) g2d.drawRect(0, 0, 50, 50); // 實際繪製在 (100,100) 到 (150,150) 區域
注意:paintIcon 的坐標參數是在當前變換後的座標系中解釋的。
getClass().getResource("logo.png"):從 classpath 加載,打包進 JAR 也能工作ImageIcon 異步加載,paintIcon 會自動等待加載完成ImageIO.read() 同步加載 BufferedImage,可控性更強代碼註釋提到「修改一下即可用在 jsp 中」,實際做法:
<%@ page import="java.awt.*, java.awt.image.*, javax.imageio.*, java.io.*" %>
<%
response.setContentType("image/png");
BufferedImage img = ImageIO.read(getClass().getResource("logo.png"));
// 創建目標圖像
BufferedImage scaled = new BufferedImage(
img.getWidth() * 2, img.getHeight() * 2, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = scaled.createGraphics();
g2d.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BICUBIC);
g2d.scale(2.0, 2.0);
g2d.drawImage(img, 0, 0, null);
g2d.dispose();
ImageIO.write(scaled, "png", response.getOutputStream());
%>
// 以圖像中心為基準縮放 int cx = img.getWidth() / 2; int cy = img.getHeight() / 2; g2d.translate(cx, cy); g2d.scale(2.0, 2.0); g2d.translate(-cx, -cy); g2d.drawImage(img, 0, 0, null);
Java 2D 的縮放機制本質是座標系仿射變換,理解「變換座標系而非圖像本身」是關鍵。結合渲染提示與合適的插值算法,可獲得高質量的圖像縮放效果,廣泛應用於圖表繪製、圖片預覽、遊戲精靈縮放等場景。