功能流程
- 載入圖片顯示在
JFrame 中。
- 滑鼠拖拽選擇矩形區域。
- 釋放滑鼠時,使用
Robot.createScreenCapture 截取屏幕對應區域。
- 將截圖保存為 JPG 文件。
核心類結構
CropImage extends JFrame:主窗口,實現 MouseListener, MouseMotionListener。
ImagePanel extends JPanel:繪製圖片的面板,覆寫 paintComponent。
關鍵代碼片段
圖片面板
class ImagePanel extends JPanel {
private final Image img;
ImagePanel(String path) { this(new ImageIcon(path).getImage()); }
ImagePanel(Image img) {
this.img = img;
Dimension size = new Dimension(img.getWidth(null), img.getHeight(null));
setPreferredSize(size);
setMinimumSize(size);
setMaximumSize(size);
setLayout(null);
}
@Override protected void paintComponent(Graphics g) {
super.paintComponent(g);
g.drawImage(img, 0, 0, null);
}
}
主窗口邏輯
public class CropImage extends JFrame implements MouseListener, MouseMotionListener {
private int dragStatus = 0, x1, y1, x2, y2;
private final ImagePanel imagePanel;
public CropImage(String imagePath) {
imagePanel = new ImagePanel(imagePath);
add(imagePanel);
pack(); // 自適應圖片大小
setLocationRelativeTo(null);
setDefaultCloseOperation(EXIT_ON_CLOSE);
addMouseListener(this);
addMouseMotionListener(this);
}
@Override public void mousePressed(MouseEvent e) {
x1 = e.getX(); y1 = e.getY();
dragStatus = 0;
repaint();
}
@Override public void mouseDragged(MouseEvent e) {
x2 = e.getX(); y2 = e.getY();
dragStatus = 1;
repaint(); // 觸發 paint 畫選區矩形
}
@Override public void mouseReleased(MouseEvent e) {
if (dragStatus == 1) {
x2 = e.getX(); y2 = e.getY();
captureAndSave();
}
}
@Override public void paint(Graphics g) {
super.paint(g);
if (dragStatus == 1) {
int w = Math.abs(x2 - x1);
int h = Math.abs(y2 - y1);
int x = Math.min(x1, x2);
int y = Math.min(y1, y2);
g.drawRect(x, y, w, h); // 畫虛線矩形更佳
}
}
private void captureAndSave() {
try {
int x = Math.min(x1, x2);
int y = Math.min(y1, y2);
int w = Math.abs(x2 - x1);
int h = Math.abs(y2 - y1);
Rectangle rect = new Rectangle(x, y, w, h);
BufferedImage capture = new Robot().createScreenCapture(rect);
ImageIO.write(capture, "JPG", new File("cropped.jpg"));
System.out.println("裁剪圖片已保存: cropped.jpg");
} catch (Exception ex) {
ex.printStackTrace();
}
}
// 未使用的滑鼠事件方法留空...
public static void main(String[] args) {
SwingUtilities.invokeLater(() -> new CropImage("test.jpg").setVisible(true));
}
}
注意事項與改進方向
- 座標偏移:
Robot.createScreenCapture 使用屏幕絕對座標,需將組件相對座標轉換為屏幕座標(SwingUtilities.convertPointToScreen)。
- 高 DPI:縮放環境下截圖模糊,需配置
sun.java2d.uiScale.enabled=false 或使用 GraphicsConfiguration.createCompatibleImage 直接從組件繪制。
- 更佳體驗:在
ImagePanel 內部處理選區繪製與截圖(BufferedImage.getSubimage),避免屏幕座標轉換與遮擋問題。
- 選區調整:支持拖拽邊緣/角調整大小、鍵盤微調。