Comment savoir si un Graphique.drawImage() est réellement terminée

C'est ma première fois de poser une question sur ici, et je suis en espérant obtenir une réponse ou une idée qui va m'aider.

Je dessine une image de grande dimension et de mise à l'échelle vers le bas avec drawImage(). J'ai alors tout de suite une autre image avec drawImage() que je m'attends à être tiré sur le dessus de la précédente (à la seconde). Le problème est que drawImage retourne immédiatement, même si il faut ~50 ms à l'échelle et le rendu de la première image. La plupart du temps la deuxième image se termine sous le premier parce que c'est peint à la première tandis que la première est en cours de traitement. En gros est-il de toute façon à force de drawImage() bloque jusqu'à ce qu'il fait, ou de quelque sorte de vérifier quand il a terminé?

Je suis conscient de la ImageObserver paramètre, qui fonctionne très bien lors du téléchargement d'une image à partir d'Internet ou quelque chose, mais lors de l'utilisation d'un déjà-chargé BufferedImage, il n'est jamais déclenché ImageUpdate() juste après la mise à l'échelle et le dessin. Essentiellement depuis la première image est déjà "chargé", il ne touche jamais le ImageObserver, il faut juste faire comme ~50 ms dans son propre thread de processus, de ne jamais notifier lorsqu'elle est terminée.

Personne ne sait comment à force de bloquer ou d'attendre jusqu'à ce qu'il est entièrement fait de mise à l'échelle et de blitting une image? Et, évidemment, à l'aide de Fil.sommeil(xx) est un hack et pas viable en raison des différences entre la vitesse de l'ordinateur. Tout cela rendu est arrivé sur l'Événement de fil à l'intérieur de l'paint(Graphics g) de la méthode.

Merci!

EDIT: voici le code que j'ai actuellement ont pour vous donner une idée de la question:

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();
}

EDIT 2: Pour mieux expliquer le problème dont je parle, j'ai fait un exemple de code qui fait mieux ce que j'essaie d'expliquer. Exécutez-le et vous allez voir le scintillement où, parfois, la première image est sur le fond (comme il est censé l'être), mais la plupart du temps, il sera un top (seconde), ce qui est faux. Il suffit de changer les chemins d'accès à une petite image et une grande image.

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;
    }
}
  • Je ne peux pas déterminer quand Java seront effectivement rendre la sortie de l'objet Graphique. La seule chose que vous pouvez vous assurer c'est que cela n'arrivera pas jusqu'à ce que APRÈS la méthode de peinture renvoie, de sorte que le Fil.le sommeil est de ne rien faire d'autre alors ralentir votre programme. Si vous êtes à la peinture par le biais d'un Composant quelconque, le passer à la drawInage que la méthode ImageObserver & laissez la mise à jour de lui-même quand il est prêt. L'autre choix est à l'échelle de l'image dans un thread d'arrière-plan
  • public class Main extends Applet.. Qui ne fonctionne pas ici, puisque cette applet utilisé des images qui ne sont pas sur les disques locaux. Les Applets sont également plus difficile pour les personnes à exécuter que les applications. Je vous suggère de poster une image basée sur SSCCE que ce soit à chaud des liens vers des images ou de les générer dans le code.
InformationsquelleAutor Jacob | 2013-01-26