【发布时间】:2011-10-07 03:00:46
【问题描述】:
一种尝试的方法是使用TexturePaint 和g.fillRect() 来绘制图像。但是,这需要您在每次绘制图像时创建一个新的 TexturePaint 和 Rectangle2D 对象,这并不理想 - 无论如何也无济于事。
当我使用g.drawImage(BufferedImage,...) 时,旋转后的图像显得模糊/柔和。
我熟悉 RenderingHints 和双缓冲(我想这就是我正在做的事情),我只是觉得很难相信您不能轻松有效地旋转在 Java 中生成清晰结果的图像。
使用TexturePaint 的代码如下所示。
Grahics2D g2d = (Graphics2D)g;
g2d.setPaint(new TexturePaint(bufferedImage, new Rectangle2D.Float(0,0,50,50)));
g2d.fillRect(0,0,50,50);
我正在使用AffineTransform 将手牌旋转成扇形。
快速绘制漂亮图像的最佳方法是什么?
这是截图:
9 很清晰,但其余的牌肯定没有那么清晰。
问题可能出在我创建每个卡片图像并将其存储在数组中时。
这是我目前的做法:
// i from 0 to 52, card codes.
...
GraphicsEnvironment ge = GraphicsEnvironment.getLocalGraphicsEnvironment();
GraphicsDevice gs = ge.getDefaultScreenDevice();
GraphicsConfiguration gc = gs.getDefaultConfiguration();
BufferedImage img = gc.createCompatibleImage(86, 126, Transparency.TRANSLUCENT);
Graphics2D g = img.createGraphics();
setRenderingHints(g);
g.drawImage(shadow, 0, 0, 86, 126, null);
g.drawImage(white, 3, 3, 80, 120, null);
g.drawImage(suit, 3, 3, 80, 120, null);
g.drawImage(value, 3, 3, 80, 120, null);
g.dispose();
cardImages[i] = img;
}
private void setRenderingHints(Graphics2D g){
g.setRenderingHint(KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
g.setRenderingHint(KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
g.setRenderingHint(KEY_ANTIALIASING, VALUE_ANTIALIAS_ON);
}
我应该如何以不同的方式处理这个问题? 谢谢。
编辑:
没有渲染提示
设置 AA 提示没有任何区别。此外,在创建图像时设置 RenderingHints 也没有什么区别。只有当它们使用AffineTransform 旋转并使用g.drawImage(...) 绘制时,它们似乎才会模糊。
上图显示了默认(最近邻)和双线性插值之间的区别。
这是我目前绘制它们的方式(比 TexturePaint 快得多):
// GamePanel.java
private void paintCard(Graphics2D g, int code, int x, int y){
g.drawImage(imageLoader.getCard(code), x, y, 86, 126, null);
}
// ImageLoader.java
public BufferedImage getCard(int code){
return cardImages[code];
}
我所有的卡片都是80x120,阴影.png是86x126,这样在卡片周围留下3px的半透明阴影。我知道这不是一个真实的阴影,但看起来还不错。
所以问题就变成了...... 如何在旋转 BufferedImage 时产生清晰的绘制结果?
参考上一个关于扇形牌手的问题:
How can you detect a mouse-click event on an Image object in Java?
赏金编辑: 好的,经过多次讨论,我制作了一些测试 .svg 卡,看看 SVG Salamander 将如何渲染它们。不幸的是,性能很糟糕。我的实现足够干净,看到双缓冲 BufferedImage 的绘画速度非常快。这意味着我已经完成了一个完整的循环,我又回到了原来的问题。
我会将 50 赏金奖励给任何能给我提供解决方案来获得锐利 BufferedImage 旋转的人。建议在绘画之前使图像大于所需大小并缩小比例,并使用双三次插值。如果这些是唯一可能的解决方案,那么我真的不知道从哪里开始,我可能只需要处理模糊的旋转 - 因为这两者都会造成性能挫折。
如果我能找到办法做好这件事,我就能完成我的游戏。 谢谢大家。 :)
【问题讨论】:
-
我看不到你在哪里设置
RenderingHints。 -
@Moonbeam:RenderingHints 对图像没有帮助,而仅对我们绘制的形状有帮助。如果您查看 API,它指出:“ANTIALIASING 提示控制 Graphics2D 对象的几何渲染方法是否会尝试减少沿形状边缘的锯齿伪影。”所以他是对的甚至不要在这里尝试使用它们。
-
@Rudi:如果你在内存图像中保持更大的尺寸,并在可视化之前旋转后缩小尺寸怎么办?
-
@paranoid-android 将图像旋转任意角度意味着破坏数据;图像越大,丢失的数据越少,因此如果您负担不起切换到矢量图形,它可能是唯一的选择
-
@paranoid-android 因为我只给出了一个提示而没有实现,如果你用一些示例代码回答自己并接受它会更好。请注意,我没有建议放大(这是有损的),只是为了在可视化之前保持更大的图像并缩小
标签: java transform transformation interpolation bufferedimage