Java JLabel
图标在JFrame
中显示为像素变形。对于不同的png图像(全部为32x32),这会始终发生。我没有缩放图像,它们显示在程序32x32中,我在JLabel上使用getWidth
和getHeight
进行了验证。每次运行程序时,变形会出现在同一位置,而不是随机出现。
在此屏幕截图中,您可以看到一系列JLabel图标,每个图标的影响方式不同。
从侧面调整窗口大小时,随着图标与窗口一起移动,变形会像垂直线一样在图标上移动。
import javax.imageio.ImageIO;
import javax.swing.*;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.net.URL;
public class FrameApp extends JFrame
{
public static void main(String[] args) throws IOException
{
FrameApp frameApp = new FrameApp();
}
private FrameApp() throws IOException
{
BufferedImage image;
URL url = new URL("http://i.stack.imgur.com/L5DGx.png");
image = ImageIO.read(url);
JLabel label = new JLabel(new ImageIcon(image));
add(label);
pack();
setVisible(true);
setDefaultCloseOperation(WindowConstants.EXIT_ON_CLOSE);
}
}
修改:
我在Windows 8.1 64位上使用JDK 11.0.3,Java SE Runtime Environment构建1.8.0_202。
答案 0 :(得分:3)
您可能会认为您正在以32x32的尺寸显示图像,但是您平铺图像的示例却并非如此。您有一个9x2的图标网格,应为288x64像素,但在示例图像中,该网格为302x66。
如果您仔细检查平铺的图像,可以看到单个平铺的显示宽度为34px-洋红色边框从32px扩展到66px。 (请注意,某些磁贴显示为33px宽;它看起来是33、34、34、33、34 ...)
为了将图块拉伸到更大的宽度,某些列被加倍(红色边框),这会产生您所看到的视觉故障。
您是否尝试过固定JLabel的大小,而不是根据其内容来调整其大小?
答案 1 :(得分:1)
第一个选项: 您可以尝试使用graphics.drawImage(x,y,width,height,null)控制渲染质量(https://docs.oracle.com/javase/tutorial/2d/advanced/quality.html)
来创建自己的图标类,而不是使用ImageIcon。一个例子就是这样:
public class Icon32 extends ImageIcon {
public Icon32(String f) {
super(f);
BufferedImage i= new BufferedImage(32, 32,
BufferedImage.TYPE_INT_RGB);
Graphics2D g2d = (Graphics2D) i.getGraphics();
g2d.setRenderingHint(
RenderingHints.KEY_ANTIALIASING,
RenderingHints.VALUE_ANTIALIAS_ON);
g2d.setRenderingHint(
RenderingHints.KEY_INTERPOLATION,
RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g2d.drawImage(getImage(), 0, 0, 32, 32, null);
setImage(i);
}
public int getIconHeight() {
return 32;
}
public int getIconWidth() {
return 32;
}
public void paintIcon(Component c, Graphics g, int x, int y) {
g.drawImage(getImage(), x, y, c);
}
}
其中的方法:
getImage()
正在加载图片/图标...
第二个选项:如果您对结果不满意,可以尝试使用此库: https://github.com/mortennobel/java-image-scaling 它声称提供了比Java运行时更好的图像缩放选项。
答案 2 :(得分:0)
Answer is from this link to generate high quality image
: https://componenthouse.com/2008/02/08/high-quality-image-resize-with-java/
链接中的相应课程:
public class ImageResize {
public static void main(String[] args) {
try {
URL url = new URL("http://i.stack.imgur.com/L5DGx.png");
BufferedImage image = ImageIO.read(url);
ImageIO.write(resizeImage(image, 32, 32), "png", new File("D:/picture3.png"));
} catch (IOException e) {
e.printStackTrace();
}
}
private static BufferedImage resize(BufferedImage image, int width, int height) {
int type = image.getType() == 0? BufferedImage.TYPE_INT_ARGB : image.getType();
BufferedImage resizedImage = new BufferedImage(width, height, type);
Graphics2D g = resizedImage.createGraphics();
g.setComposite(AlphaComposite.Src);
g.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
g.drawImage(image, 0, 0, width, height, null);
g.dispose();
return resizedImage;
}
private static BufferedImage resizeImage(BufferedImage image, int width, int height) {
image = createCompatibleImage(image);
image = resize(image, 100, 100);
image = blurImage(image);
return resize(image, width, height);
}
public static BufferedImage blurImage(BufferedImage image) {
float ninth = 1.0f/9.0f;
float[] blurKernel = {
ninth, ninth, ninth,
ninth, ninth, ninth,
ninth, ninth, ninth
};
Map<RenderingHints.Key, Object> map = new HashMap<RenderingHints.Key, Object>();
map.put(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR);
map.put(RenderingHints.KEY_RENDERING,RenderingHints.VALUE_RENDER_QUALITY);
map.put(RenderingHints.KEY_ANTIALIASING,RenderingHints.VALUE_ANTIALIAS_ON);
RenderingHints hints = new RenderingHints(map);
BufferedImageOp op = new ConvolveOp(new Kernel(3, 3, blurKernel), ConvolveOp.EDGE_NO_OP, hints);
return op.filter(image, null);
}
private static BufferedImage createCompatibleImage(BufferedImage image) {
GraphicsConfiguration gc = BufferedImageGraphicsConfig.getConfig(image);
int w = image.getWidth();
int h = image.getHeight();
BufferedImage result = gc.createCompatibleImage(w, h, Transparency.TRANSLUCENT);
Graphics2D g2 = result.createGraphics();
g2.drawRenderedImage(image, null);
g2.dispose();
return result;
}
}