exi*_*t_1 19 java swing background-image jpanel aspect-ratio
我有一个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);
}
}
Run Code Online (Sandbox Code Playgroud)
编辑:我应该提到我知道宽高比公式: 原始高度/原始宽度x新宽度=新高度 然而,我不知道如何正确使用它对我有利.
Mad*_*mer 44
那么,最快捷,最简单的解决方案就是使用 Image.getScaledInstance
g.drawImage(img.getScaledInstance(newWidth, -1, Image. SCALE_SMOOTH), x, y, this);
Run Code Online (Sandbox Code Playgroud)
如果您对负数感到疑惑,那么java文档会说:
如果宽度或高度是负数,则替换值以保持原始图像尺寸的纵横比.如果宽度和高度都为负,则使用原始图像尺寸.
UPDATE
就像一个旁注(我的谷歌正在播放).
getScaledInstance 既不是最快或最高质量的方法,但它是最简单的方法.
阅读Image.getScaledInstance的Perils阅读更多想法
UPDATE
缩放图像以适合某个区域比仅缩放纵横比稍微复杂一些.如果您希望图像在区域内"适合"(可能在其周围留下空白区域)或"填充"该区域(以使其最小尺寸适合该区域的最大尺寸),则必须做出选择.


适合和填充
基本上,我使用比例因子
这将返回特定大小的缩放系数.我用它根据我需要的算法决定我想要使用哪个因素
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;
}
Run Code Online (Sandbox Code Playgroud)
它被这两种方法使用.他们只需要两个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;
}
Run Code Online (Sandbox Code Playgroud)
将图像传入(直接或通过支持方法)相对简单.例如,您可以在paint方法中调用它
double factor getScaledFactorToFit(new Dimension(image.getWidth(), image.getHeight()), getSize());
int scaledWidth = image.getWidth() * scale;
int scaledHeight *= image.getWidth() * scale;
Run Code Online (Sandbox Code Playgroud)
这将自动为您处理宽高比;)
更新了扩展示例
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);
}
Run Code Online (Sandbox Code Playgroud)
| 归档时间: |
|
| 查看次数: |
27290 次 |
| 最近记录: |