这是我第一次在这里提出问题,我希望我能得到一个对我有帮助的答案或想法。
我正在绘制一个大图像并使用 drawImage() 将其缩小。然后,我立即使用 drawImage() 绘制另一个图像,我希望将其绘制在前一个图像之上(第二个)。问题是 drawImage 会立即返回,即使缩放和渲染第一张图像需要大约 50 毫秒。大多数情况下,第二张图片最终位于第一张图片下方,因为它是在处理第一张大图片时首先绘制的。基本上无论如何都要强制 drawImage() 阻塞直到它完成,或者以某种方式检查它何时完成?
我知道 ImageObserver 参数,它在从 Internet 或其他地方下载图像时工作正常,但是当使用已经加载的 BufferedImage 时,它永远不会在缩放和绘图之后触发 ImageUpdate()。基本上,由于第一个图像已经“加载”,它永远不会联系 ImageObserver,它只需要大约 50 毫秒的时间在它自己的线程中处理,从不通知它何时完成。
有谁知道如何强制它阻止或等到它完全完成缩放和 blitting 图像?显然,使用 Thread.sleep(xx) 是一种完全的黑客行为,由于计算机速度之间的差异,它是不可行的。所有这些渲染都发生在paint(Graphics g) 方法内的事件线程上。
谢谢!
编辑:以下是我目前必须让您了解该问题的代码:
public void paint(Graphics window)
{
window.setColor(Color.WHITE);
window.fillRect(0, 0, Settings.width * Settings.aaFactor, Settings.height * Settings.aaFactor);
Graphics2D window2D = (Graphics2D) window;
window2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
window2D.drawImage(this.image, 0, 0, Settings.width, Settings.height, null);
try
{
Thread.sleep(50);
}
catch (InterruptedException e)
{
e.printStackTrace();
}
window2D.drawImage(this.image2, 0, 0, null);
repaint();
}
编辑2:为了更好地解释我正在谈论的问题,我制作了一些示例代码,可以更好地解释我想要解释的内容。运行它,你会看到它在有时第一张图像在底部的地方闪烁(就像它应该是的那样),但大多数时候它会在顶部(第二张),这是错误的。只需将文件路径更改为小图像和大图像。
public class Main extends Applet implements ImageObserver
{
private BufferedImage imageA;
private BufferedImage imageB;
@Override
public void init()
{
try
{
this.imageA = ImageIO.read(new File("C:\\LargeImage.jpg"));
this.imageB = ImageIO.read(new File("C:\\SmallImage.jpg"));
}
catch (IOException e)
{
e.printStackTrace();
}
}
@Override
public void update(Graphics g)
{
paint(g);
}
@Override
public void paint(Graphics g)
{
Graphics2D w = (Graphics2D) g;
w.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BICUBIC);
w.drawImage(this.imageA, 0, 0, 50, 50, this);// This takes a while to do (scaling down and drawing)...
w.drawImage(this.imageB, 10, 10, null);// While this is drawn quickly, before A is done.
repaint();
}
@Override
public boolean imageUpdate(Image img, int infoflags, int x, int y, int width, int height)
{
System.out.println("ImageObserver fired, done drawing image. NEVER CALLED!");
return false;
}
}