首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
社区首页 >问答首页 >当旋转BufferedImage时,如何产生尖锐的油漆效果?

当旋转BufferedImage时,如何产生尖锐的油漆效果?
EN

Stack Overflow用户
提问于 2011-07-17 04:56:21
回答 3查看 3.4K关注 0票数 25

一种尝试的方法是使用TexturePaintg.fillRect()来绘制图像。然而,这要求您每次绘制图像时都要创建一个新的TexturePaint和Rectangle2D对象,这并不理想,而且也没有帮助。

当我使用g.drawImage(BufferedImage,...)时,旋转的图像看起来很模糊/柔软。

我熟悉RenderingHints和双缓冲(我认为这就是我正在做的),我只是觉得很难相信在Java中很难轻松有效地旋转图像,从而产生尖锐的结果。

使用TexturePaint的代码如下所示。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
Grahics2D g2d = (Graphics2D)g; 
g2d.setPaint(new TexturePaint(bufferedImage, new Rectangle2D.Float(0,0,50,50)));
g2d.fillRect(0,0,50,50);

我用AffineTransform把一只手牌旋转成扇子。快速绘制漂亮图像的最佳方法是什么?

这是一个截图:

9是脆的,但其余的牌肯定没有那么锋利。

问题可能在于当我创建每个卡片映像并将其存储在一个数组中时。

我现在是这样做的:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 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);
}

我该如何以不同的方式对待这件事?谢谢。

编辑:

无RenderingHints

设置AA提示没有什么不同。此外,在创建图像时设置RenderingHints也没有什么区别。只有当它们使用AffineTransform旋转并使用g.drawImage(...)绘制时,它们才显得模糊。

上面的图像显示了缺省(最近邻)和双线性插值之间的区别。

下面是我当前绘制它们的方式(比TexturePaint快得多):

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
// 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时,如何产生尖锐的油漆效果?

还提及先前关于扇形牌手的一个问题:

如何检测Java中Image对象上的鼠标单击事件?

好的,经过大量讨论,我做了几个测试Bounty-Edit:卡,看看Salamander会如何渲染它们。不幸的是,演出糟透了。我的实现已经足够干净了,就像使用双缓冲缓冲区图像(BufferedImage)的画图一样,画得非常快。这意味着我已经走了一圈,我又回到了原来的问题。

我会给谁的50赏金,谁能给我一个解决方案,以得到尖锐的BufferedImage旋转。建议是使图像比他们需要的更大,并在绘画前缩小比例,并使用双三次插值。如果这是唯一可能的解决方案,那么我真的不知道从哪里开始,我可能只需要处理模糊的旋转-因为这两种方法都会造成性能上的挫折。

如果我能找到办法把这件事做好,我就能完成我的游戏。感谢每个人。:)

EN

回答 3

Stack Overflow用户

回答已采纳

发布于 2011-07-28 04:41:20

旋转光栅化图像(如BufferedImage)时,会丢失数据。最好的解决方案是保存比你需要的图像更大的图像,并在你绘制图片时立即缩小它们的比例。我发现1.5倍的大小是一个很好的起点。

然后,当您正在绘制图像时,动态调整大小:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
g.drawImage(bufferedImage, x, y, desiredWidth, desiredHeight, observer);

推荐使用双线性插值进行旋转。

建议的功劳归于吉多。

票数 9
EN

Stack Overflow用户

发布于 2011-07-17 11:41:20

在您的设计中,这个建议可能有点晚,但可能值得一提。

如果很多旋转和动画都是UI的一部分,那么使用光栅化图像可能是错误的技术;特别是对于具有大量曲线的复杂图像。等你试着放大你的画布。我可能会建议看一个基于向量的图形库。它们将呈现出您想要的效果,而工件的潜力则较小。

http://xmlgraphics.apache.org/batik/using/swing.htm

票数 5
EN

Stack Overflow用户

发布于 2011-07-17 11:02:56

AffineTransformOp中设置插值类型以及抗混叠值可能会提供一些改进.类型TYPE_BICUBIC虽然速度较慢,但通常是最好的质量;示例概述了这里。注意,您可以提供多个RenderingHints。另一个陷阱是由于每次渲染图像时没有应用提示而产生的。您还可能需要调整背景的透明度,如建议的这里。最后,考虑创建包含实际映像之一的斯考斯

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/6723929

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
查看详情【社区公告】 技术创作特训营有奖征文