我有一个JPanel
,带有一个绘制的背景图像,一个布局管理器保存着其他较小的图像,所有这些都放在JFrame
中。背景图像非常大,我希望它能够在大型或小型显示器上保持其纵横比。
最终,我希望能够将我的LayoutManager
和其单元格中的较小图像“粘合”到背景图片。
我四处寻找资源,似乎很多示例都使用了BufferedImage
,但我没有使用;这会带来问题吗?我将在下面发布用于绘制图像的代码,如果我缺少任何信息,请告诉我。
public class MonitorPanel extends JPanel {
Image img;
public MonitorPanel() throws MalformedURLException {
//add components
try {
img = ImageIO.read(new File("src/customer_vlans.jpg"));
} catch (IOException e) {
// TODO Auto-generated catch block
e.printStackTrace();
}
}
protected void paintComponent(Graphics g)
{
//paint background image
super.paintComponent(g);
//g.drawImage(img, 0, 0, getWidth(), getHeight(), this);
g.drawImage(img, 0, 0, this);
}
}
EDIT:我应该提到我知道纵横比公式:原始高度/原始宽度x新宽度=新高度但是,我不知道如何正确地使用它来发挥自己的优势。
嗯,最快最简单的解决方案是使用Image.getScaledInstance
g.drawImage(img.getScaledInstance(newWidth, -1, Image. SCALE_SMOOTH), x, y, this);
如果您想知道负数,则Java文档会说:
如果宽度或高度为负数,则值为替换以保持原始图像的长宽比尺寸。如果宽度和高度均为负数,则原始使用图像尺寸。
UPDATE
作为旁注(我的Google正在播放)。
getScaledInstance
既不是最快的方法也不是最高质量的方法,但这是最简单的方法。
阅读The Perils of Image.getScaledInstance以获得更多建议
UPDATE
缩放图像以适合某个区域要稍微复杂一些,然后再简单地缩放纵横比即可。如果要让图像“适合”该区域(可能在其周围留有空白区域),或者要“填充”该区域(以使其最小尺寸适合该区域的最大尺寸),则必须做出选择。 >
Fit&Fill
基本上,我使用比例因子
这将返回特定尺寸的缩放比例。我根据自己需要的算法来决定要使用的因素]
public static double getScaleFactor(int iMasterSize, int iTargetSize) { double dScale = 1; if (iMasterSize > iTargetSize) { dScale = (double) iTargetSize / (double) iMasterSize; } else { dScale = (double) iTargetSize / (double) iMasterSize; } return dScale; }
被这两种方法使用。他们只需要两个
Dimension
。原件和目标。
中调用此方法public static double getScaleFactorToFit(Dimension original, Dimension toFit) { double dScale = 1d; if (original != null && toFit != null) { double dScaleWidth = getScaleFactor(original.width, toFit.width); double dScaleHeight = getScaleFactor(original.height, toFit.height); dScale = Math.min(dScaleHeight, dScaleWidth); } return dScale; } public static double getScaleFactorToFill(Dimension masterSize, Dimension targetSize) { double dScaleWidth = getScaleFactor(masterSize.width, targetSize.width); double dScaleHeight = getScaleFactor(masterSize.height, targetSize.height); double dScale = Math.max(dScaleHeight, dScaleWidth); return dScale; }
直接或通过支持方法将图像传递到其中相对简单。因此,例如,您可以从
paint
方法
double factor getScaledFactorToFit(new Dimension(image.getWidth(), image.getHeight()), getSize()); int scaledWidth = image.getWidth() * scale; int scaledHeight *= image.getWidth() * scale;
这将自动为您照顾长宽比;)
使用扩展示例进行更新
public double getScaleFactor(int iMasterSize, int iTargetSize) {
double dScale = 1;
if (iMasterSize > iTargetSize) {
dScale = (double) iTargetSize / (double) iMasterSize;
} else {
dScale = (double) iTargetSize / (double) iMasterSize;
}
return dScale;
}
public double getScaleFactorToFit(Dimension original, Dimension toFit) {
double dScale = 1d;
if (original != null && toFit != null) {
double dScaleWidth = getScaleFactor(original.width, toFit.width);
double dScaleHeight = getScaleFactor(original.height, toFit.height);
dScale = Math.min(dScaleHeight, dScaleWidth);
}
return dScale;
}
@Override
protected void paintComponent(Graphics g) {
super.paintComponent(g);
double scaleFactor = Math.min(1d, getScaleFactorToFit(new Dimension(image.getWidth(), image.getHeight()), getSize()));
int scaleWidth = (int) Math.round(image.getWidth() * scaleFactor);
int scaleHeight = (int) Math.round(image.getHeight() * scaleFactor);
Image scaled = image.getScaledInstance(scaleWidth, scaleHeight, Image.SCALE_SMOOTH);
int width = getWidth() - 1;
int height = getHeight() - 1;
int x = (width - scaled.getWidth(this)) / 2;
int y = (height - scaled.getHeight(this)) / 2;
g.drawImage(scaled, x, y, this);
}
尝试这样的事情:
对于有兴趣按以下方式通过MadProgrammer修改PaintComponent方法的任何人都可以更快地更新显示内容
我想出了这个解决方案: