Простой bufferedimage, мерцающий при вызове repaint

#java #swing #repaint #flicker

#java #качели #перерисовка #мерцание

Вопрос:

Я пытаюсь создать вид с веб-камеры с помощью OpenCV, но когда я перерисовываю сохраненное изображение, оно мерцает, и иногда изображения выглядят наполовину серыми.

 import java.awt.Graphics;
    import java.awt.image.BufferedImage;
    import java.io.File;
    import java.io.IOException;
    import javax.imageio.ImageIO;
    import javax.swing.JPanel;

    public class Panel extends JPanel {

    BufferedImage img;
    public Panel() {
        super(true);
    }

    public void paintComponent(Graphics g) {
        super.paintComponent(g);


        try {
            img = ImageIO.read(new File("webcam.jpg"));
        } catch (IOException e) {
            e.printStackTrace();
        }
        g.drawImage(img, 0, 0, 640, 480, this);
        repaint();
    }
}
 

Ответ №1:

Не считывайте свое изображение в вашем методе paintComponent(). Прочитайте изображение в вашем конструкторе.

Кроме того, не вызывайте repaint() из вашего метода paintComponent() . Если вам нужно постоянно перерисовывать, используйте поток или таймер.

Редактировать: это может потребовать некоторой настройки, но это базовый подход, о котором я говорю:

 import java.awt.Graphics;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.JPanel;

public class Panel extends JPanel implements Runnable{

BufferedImage img;
public Panel() {
    super(true);
    new Thread(this).start();
}

public void paintComponent(Graphics g) {
    super.paintComponent(g);

    if(img != null){
        synchronized(this){
            g.drawImage(img, 0, 0, 640, 480, this);
        }
    }
}

public void run(){
    while(true){
        try {
            synchronized(this){
                img = ImageIO.read(new File("webcam.jpg"));
            }
        } catch (IOException e) {
            e.printStackTrace();
        }

        repaint();

        try {
            Thread.sleep((long) (1000.0/30));
        } 
        catch (InterruptedException e) {
            e.printStackTrace();
        }
    }
}
}
 

Комментарии:

1. но тогда изображение считывается только один раз и не обновляется. Другой класс (SaveImage) сохраняет изображение веб-камеры в webcam.jpg каждые 10 миллисекунд

2. Итак, я должен создать поток для конструктора, который считывает изображение, а также перерисовывает? и рисовать изображение только в paintcomponent?

3. Спасибо! это должен быть правильный способ его рисования. Это все еще вызывает у меня некоторое серое мерцание, но может быть, проблема в том, что opencv сохраняет фотографии. Вероятно, я неправильно использую API, поскольку для Java доступно мало документации

4. Вы также можете столкнуться с ситуацией, когда файл перезаписывается во время его загрузки. Возможно, вы захотите использовать какую-то систему индексации или что-то в этом роде вместо записи / чтения из одного и того же файла снова и снова.

5. Да, так оно и было. Я сменил 1 файл на 3 файловую систему, и теперь она работает чисто. Еще раз спасибо!