程序在 Thread.sleep() 期间和计时器冻结
原始问题:
此方法应该将 JFrame 上显示的图像逐渐更改为另一个图像。然而,如果没有某种方法减慢它的速度,它似乎只是从一张图像变成了新图像。为了减慢速度,我放入了 Thread.sleep(1000),这样更改就不会立即发生。然而,有了这一行,我的程序就完全冻结了。没有错误消息,什么也没有。有人可以帮我吗?建议一种更好的方法来减慢速度,或者如何解决这个问题。
澄清一下:int k 是变化中的渐进步骤数。 k = 1 将是瞬时变化。任何更大的改变都将是渐进的。 int l 同时控制每张图像显示的比例。
public void morphImg(int width, int height, BufferedImage morphImage, int k) {
//creates new image from two images of same size
BufferedImage image2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
//get color from original image
Color c = new Color(image.getRGB(i, j));
//get colors from morph image
Color c2 = new Color(morphImage.getRGB(i, j));
for (int l = 1; l <= k; l++) {
//gets colors at different stages
int r = ((k-l)*c.getRed()/k) + (l*c2.getRed()/k);
int g = ((k-l)*c.getGreen()/k) + (l*c2.getGreen()/k);
int b = ((k-l)*c.getBlue()/k) + (l*c2.getBlue()/k);
Color newColor = new Color(r, g, b);
//set colors of new image to average of the two images
image2.setRGB(i, j, newColor.getRGB());
//display new image
try {
imageLabel.setIcon(new ImageIcon(image2));
Thread.sleep(1000);
}
catch (InterruptedException e){
System.out.println("Exception caught.");
}
}
}
}
//sets modified image as "original" for further manipulation
setImage(image2);
}
更新的代码:使用计时器也会导致程序冻结...我使用得不对吗?
public void morphImg(int width, int height, BufferedImage morphImage, int k) {
//creates new image from two images of same size
final BufferedImage image2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int l = 1; l <= k; l++) {
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
//get color from original image
Color c = new Color(image.getRGB(i, j));
//get colors from morph image
Color c2 = new Color(morphImage.getRGB(i, j));
//gets colors at different stages
int r = ((k-l)*c.getRed()/k) + (l*c2.getRed()/k);
int g = ((k-l)*c.getGreen()/k) + (l*c2.getGreen()/k);
int b = ((k-l)*c.getBlue()/k) + (l*c2.getBlue()/k);
Color newColor = new Color(r, g, b);
//set colors of new image to average of the two images
image2.setRGB(i, j, newColor.getRGB());
//display new image
imageLabel.setIcon(new ImageIcon(image2));
final Timer t = new Timer(500,null);
t.setInitialDelay(500);
t.start();
}
}
}
//sets modified image as "original" for further manipulation
setImage(image2);
}
Original question:
This method is supposed to change the image being displayed on a JFrame gradually into another image. However, without some way to slow it down, it just seems to change from one image to the new image. In order to slow it down, I put in a Thread.sleep(1000) so the changes wouldn't happen instantly. However, with this line in there, my program freezes completely. No error message, no nothing. Can anyone please help me out? Suggest a better method to slow it down, or how this can be fixed.
For clarification: int k is the number of gradual steps in the change. k = 1 would be an instant change. Anything greater would be gradual changes. int l meanwhile controls the ratio of how much of each image is displayed.
public void morphImg(int width, int height, BufferedImage morphImage, int k) {
//creates new image from two images of same size
BufferedImage image2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
//get color from original image
Color c = new Color(image.getRGB(i, j));
//get colors from morph image
Color c2 = new Color(morphImage.getRGB(i, j));
for (int l = 1; l <= k; l++) {
//gets colors at different stages
int r = ((k-l)*c.getRed()/k) + (l*c2.getRed()/k);
int g = ((k-l)*c.getGreen()/k) + (l*c2.getGreen()/k);
int b = ((k-l)*c.getBlue()/k) + (l*c2.getBlue()/k);
Color newColor = new Color(r, g, b);
//set colors of new image to average of the two images
image2.setRGB(i, j, newColor.getRGB());
//display new image
try {
imageLabel.setIcon(new ImageIcon(image2));
Thread.sleep(1000);
}
catch (InterruptedException e){
System.out.println("Exception caught.");
}
}
}
}
//sets modified image as "original" for further manipulation
setImage(image2);
}
UPDATED CODE: Using a Timer also causes the program to freeze...Am I not using it right?
public void morphImg(int width, int height, BufferedImage morphImage, int k) {
//creates new image from two images of same size
final BufferedImage image2 = new BufferedImage(width, height, BufferedImage.TYPE_INT_RGB);
for (int l = 1; l <= k; l++) {
for (int i = 0; i < width; i++) {
for (int j = 0; j < height; j++) {
//get color from original image
Color c = new Color(image.getRGB(i, j));
//get colors from morph image
Color c2 = new Color(morphImage.getRGB(i, j));
//gets colors at different stages
int r = ((k-l)*c.getRed()/k) + (l*c2.getRed()/k);
int g = ((k-l)*c.getGreen()/k) + (l*c2.getGreen()/k);
int b = ((k-l)*c.getBlue()/k) + (l*c2.getBlue()/k);
Color newColor = new Color(r, g, b);
//set colors of new image to average of the two images
image2.setRGB(i, j, newColor.getRGB());
//display new image
imageLabel.setIcon(new ImageIcon(image2));
final Timer t = new Timer(500,null);
t.setInitialDelay(500);
t.start();
}
}
}
//sets modified image as "original" for further manipulation
setImage(image2);
}
如果你对这篇内容有疑问,欢迎到本站社区发帖提问 参与讨论,获取更多帮助,或者扫码二维码加入 Web 技术交流群。
绑定邮箱获取回复消息
由于您还没有绑定你的真实邮箱,如果其他用户或者作者回复了您的评论,将不能在第一时间通知您!
发布评论
评论(3)
当代码在事件调度线程上执行时,切勿使用 Thread.sleep()。
相反,您应该使用 Swing Timer 来安排动画。
请参阅 Swing 教程中关于:
或者如果您不想使用计时器,那么您可以使用 SwingWorker(如并发教程中所述),然后在更改图像后发布()图像。然后您可以使用 Thread.sleep(),因为 SwingWorker 不会在 EDT 上执行。
简单定时器示例:
Never use Thread.sleep() when code is executing on the Event Dispatch Thread.
Instead you should use a Swing Timer to schedule your animation.
See the sections from the Swing tutorial on:
Or if you don't want to use a Timer, then you can use a SwingWorker (as described in the tutorial on concurrency) and then just publish() the image after you change it. Then you can use a Thread.sleep() since the SwingWorker doesn't execute on the EDT.
Simple Timer example:
k 上的循环应该是最外层的循环。现在您正在调用 Thread.sleep k*width*height 次。
The loop over k should be the outermost loop. Right now you are calling Thread.sleep k*width*height times.
如果目的是显示变形效果的渐进动画,下面是我没有使用
Timer
或Thread.sleep()
所做的测试代码,使用OP给出的最新变形代码:If the intention is to show progressive animation of the morph effect, below is the test code I did without using
Timer
orThread.sleep()
, using the latest morph code given by OP: