You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

Java如何将BufferedImage缩放到JPanel窗口并随窗口大小自适应

解决方案

第一步:纠正drawImage参数顺序误区

你之前对8参数drawImage的参数记忆有误,正确的参数顺序为:

g.drawImage(image, dx1, dy1, dx2, dy2, sx1, sy1, sx2, sy2, observer);
  • dx1:目标区域左上角X坐标
  • dy1:目标区域左上角Y坐标
  • dx2:目标区域右下角X坐标
  • dy2:目标区域右下角Y坐标
  • 后4个源区域参数你设置的逻辑正确,取0,0,image.getWidth(),image.getHeight()即可调用完整原图。

第二步:核心缩放逻辑实现

等比缩放+居中+保留内边距(无拉伸变形,通用方案)

该方案会保证图片完整显示、不变形,且始终在扣除内边距后的区域居中展示:

  1. 定义基础参数
// 自定义内边距,水平、垂直方向可单独调整
int paddingX = 10; // 对应你提到的p1
int paddingY = 10; // 对应你提到的p2

// 获取面板当前尺寸
int panelW = getWidth();
int panelH = getHeight();

// 原图尺寸
int imgW = image.getWidth();
int imgH = image.getHeight();

// 扣除内边距后的可用绘制区域
int availableW = panelW - 2 * paddingX;
int availableH = panelH - 2 * paddingY;
  1. 计算等比缩放比例
    取宽、高方向缩放比例的较小值,保证图片不会超出可用区域:
double scaleW = (double) availableW / imgW;
double scaleH = (double) availableH / imgH;
double scale = Math.min(scaleW, scaleH);
  1. 计算目标绘制区域坐标
// 缩放后图片实际宽高
int targetW = (int) (imgW * scale);
int targetH = (int) (imgH * scale);

// 计算居中偏移后的坐标
int dx1 = paddingX + (availableW - targetW) / 2;
int dy1 = paddingY + (availableH - targetH) / 2;
int dx2 = dx1 + targetW;
int dy2 = dy1 + targetH;
  1. 调用绘制方法
gr.drawImage(image, dx1, dy1, dx2, dy2, 0, 0, imgW, imgH, null);

如果你不需要保持原图比例,允许拉伸填充整个内边距区域,可直接使用简化代码:

gr.drawImage(image, paddingX, paddingY, getWidth() - paddingX, getHeight() - paddingY, 0, 0, imgW, imgH, null);

第三步:窗口大小变化同步刷新

要实现窗口调整时图片同步变化,给JPanel添加尺寸变化监听触发重绘即可:

// 在JPanel初始化时添加
addComponentListener(new ComponentAdapter() {
    @Override
    public void componentResized(ComponentEvent e) {
        repaint();
    }
});

完整可运行示例

import javax.swing.*;
import java.awt.*;
import java.awt.event.ComponentAdapter;
import java.awt.event.ComponentEvent;
import java.awt.image.BufferedImage;
import java.io.File;
import javax.imageio.ImageIO;

public class ImageScalePanel extends JPanel {
    private BufferedImage image;
    private final int paddingX = 10;
    private final int paddingY = 10;

    public ImageScalePanel(BufferedImage image) {
        this.image = image;
        // 监听尺寸变化自动重绘
        addComponentListener(new ComponentAdapter() {
            @Override
            public void componentResized(ComponentEvent e) {
                repaint();
            }
        });
    }

    @Override
    protected void paintComponent(Graphics g) {
        super.paintComponent(g);
        if (image == null) return;

        int panelW = getWidth();
        int panelH = getHeight();
        int imgW = image.getWidth();
        int imgH = image.getHeight();

        int availableW = panelW - 2 * paddingX;
        int availableH = panelH - 2 * paddingY;

        double scaleW = (double) availableW / imgW;
        double scaleH = (double) availableH / imgH;
        double scale = Math.min(scaleW, scaleH);

        int targetW = (int) (imgW * scale);
        int targetH = (int) (imgH * scale);

        int dx1 = paddingX + (availableW - targetW) / 2;
        int dy1 = paddingY + (availableH - targetH) / 2;
        int dx2 = dx1 + targetW;
        int dy2 = dy1 + targetH;

        g.drawImage(image, dx1, dy1, dx2, dy2, 0, 0, imgW, imgH, null);
    }

    public static void main(String[] args) throws Exception {
        BufferedImage img = ImageIO.read(new File("替换为你的本地图片路径"));
        JFrame frame = new JFrame("图片自适应缩放示例");
        frame.setDefaultCloseOperation(JFrame.EXIT_ON_CLOSE);
        frame.setSize(800, 600);
        frame.add(new ImageScalePanel(img));
        frame.setVisible(true);
    }
}

内容的提问来源于stack exchange,提问作者aprobeni

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.10.03 14:09:03