使图像适合 JPanel
Fit image into JPanel
我正在尝试缩放图像以使其始终适合我的 JPanel。不幸的是,使用这种方法我并不总是收到我想收到的图像。大多数情况下它是缩放的,我宁愿将整个图像缩放。
这就是创建图像的 class。 600 是面板宽度,400 是面板高度。
知道哪里出了问题吗?
public class Image extends Component{
private BufferedImage img;
protected int width;
protected int height;
private String path;
@Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
double scale = getScale(600,400,img.getWidth(),img.getHeight());
double xPos = (600 - scale * img.getWidth())/2;
double yPos = (400 - scale *img.getHeight())/2;
AffineTransform at = AffineTransform.getTranslateInstance(xPos, yPos);
at.scale(scale, scale);
g2.drawRenderedImage(img, at);
System.out.println(scale);
}
public Image(String path){
try{
img = ImageIO.read(new File(path));
} catch (IOException e) { }
this.width=img.getWidth();
this.height=img.getHeight();
this.path = path;
}
public double getScale(int panelWidth, int panelHeight, int imageWidth, int imageHeight){
double scale = 1;
double xScale, yScale;
if(imageWidth > panelWidth || imageHeight > panelHeight){
xScale = (double)imageWidth/panelWidth;
yScale = (double)imageHeight/panelHeight;
scale = Math.max(xScale, yScale);
}else if(imageWidth < panelWidth && imageHeight < panelHeight){
xScale = (double)panelWidth/imageWidth;
yScale = (double)panelHeight/imageHeight;
scale = Math.max(xScale, yScale);
}else{
scale = 1;
}
return scale;
}
如果您以正确的顺序执行操作,则不需要使用浮点数。假设imageWidth
、imageHeight
、panelWidth
都是int
:
// Calculate the width of the scaled image; if the image is wider than the
// panel, use the panel width, otherwise use the image width (i.e. don't upscale)
int scaledWidth = Math.min(imageWidth, panelWidth);
// Given the scaled width, calculate the scaled height
// Force it to be at least 1 pixel, since if you have an image that's wider than
// the panel and only 1 pixel tall, this will scale to zero height, which you
// don't want
int scaledHeight = Math.max(1, imageHeight * scaledWidth / imageWidth);
以上假设您想要适应宽度,并且如果图像高度超过面板高度,将提供滚动机制。如果你想适应高度(和溢出的水平滚动),只需对变量进行必要的更改。
JPanel 是一个 Swing 组件,这意味着您正在使用 Swing。
对于自定义绘画,您应该扩展 JPanel
或 JComponent
。大多数人使用 JPanel,因为它会为您清除组件的背景。
Swing 组件的自定义绘制是通过重写 paintComponent(...)
完成的
so it will always fit my JPanel
定义“适合”?
假设您正在尝试缩放图像以保留其原始比例,您可以这样做:
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
double imageWidth = image.getWidth(null);
double imageHeight = image.getHeight(null);
double factor = Math.min(getWidth() / imageWidth, getHeight() / imageHeight);
int width = (int)(image.getWidth(null) * factor);
int height = (int)(image.getHeight(null) * factor);
g.drawImage(image, 0, 0, width, height, this);
}
如果您只是想让图像适合面板,那么您可以:
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}
我正在尝试缩放图像以使其始终适合我的 JPanel。不幸的是,使用这种方法我并不总是收到我想收到的图像。大多数情况下它是缩放的,我宁愿将整个图像缩放。
这就是创建图像的 class。 600 是面板宽度,400 是面板高度。
知道哪里出了问题吗?
public class Image extends Component{
private BufferedImage img;
protected int width;
protected int height;
private String path;
@Override
public void paint(Graphics g) {
Graphics2D g2 = (Graphics2D)g;
g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
double scale = getScale(600,400,img.getWidth(),img.getHeight());
double xPos = (600 - scale * img.getWidth())/2;
double yPos = (400 - scale *img.getHeight())/2;
AffineTransform at = AffineTransform.getTranslateInstance(xPos, yPos);
at.scale(scale, scale);
g2.drawRenderedImage(img, at);
System.out.println(scale);
}
public Image(String path){
try{
img = ImageIO.read(new File(path));
} catch (IOException e) { }
this.width=img.getWidth();
this.height=img.getHeight();
this.path = path;
}
public double getScale(int panelWidth, int panelHeight, int imageWidth, int imageHeight){
double scale = 1;
double xScale, yScale;
if(imageWidth > panelWidth || imageHeight > panelHeight){
xScale = (double)imageWidth/panelWidth;
yScale = (double)imageHeight/panelHeight;
scale = Math.max(xScale, yScale);
}else if(imageWidth < panelWidth && imageHeight < panelHeight){
xScale = (double)panelWidth/imageWidth;
yScale = (double)panelHeight/imageHeight;
scale = Math.max(xScale, yScale);
}else{
scale = 1;
}
return scale;
}
如果您以正确的顺序执行操作,则不需要使用浮点数。假设imageWidth
、imageHeight
、panelWidth
都是int
:
// Calculate the width of the scaled image; if the image is wider than the
// panel, use the panel width, otherwise use the image width (i.e. don't upscale)
int scaledWidth = Math.min(imageWidth, panelWidth);
// Given the scaled width, calculate the scaled height
// Force it to be at least 1 pixel, since if you have an image that's wider than
// the panel and only 1 pixel tall, this will scale to zero height, which you
// don't want
int scaledHeight = Math.max(1, imageHeight * scaledWidth / imageWidth);
以上假设您想要适应宽度,并且如果图像高度超过面板高度,将提供滚动机制。如果你想适应高度(和溢出的水平滚动),只需对变量进行必要的更改。
JPanel 是一个 Swing 组件,这意味着您正在使用 Swing。
对于自定义绘画,您应该扩展 JPanel
或 JComponent
。大多数人使用 JPanel,因为它会为您清除组件的背景。
Swing 组件的自定义绘制是通过重写 paintComponent(...)
so it will always fit my JPanel
定义“适合”?
假设您正在尝试缩放图像以保留其原始比例,您可以这样做:
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
double imageWidth = image.getWidth(null);
double imageHeight = image.getHeight(null);
double factor = Math.min(getWidth() / imageWidth, getHeight() / imageHeight);
int width = (int)(image.getWidth(null) * factor);
int height = (int)(image.getHeight(null) * factor);
g.drawImage(image, 0, 0, width, height, this);
}
如果您只是想让图像适合面板,那么您可以:
@Override
protected void paintComponent(Graphics g)
{
super.paintComponent(g);
g.drawImage(image, 0, 0, getWidth(), getHeight(), this);
}