Problema pra carregar imagens

Então… o outro tópico eu fechei, aquela parte ta resolvida xD agora tem outro problema…

A transição de imagens fica piscando…alguma idéia de alguém?

Classe do efeito (extende JXImagePanel):

[code]package demo;

import java.awt.AlphaComposite;
import java.awt.EventQueue;
import java.awt.Graphics;
import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.IOException;
import javax.imageio.ImageIO;
import javax.swing.*;
import org.jdesktop.swingx.JXImagePanel;

public class Efeito2 extends JXImagePanel {

private Contador contador;
private BufferedImage img1, img2, img3, img4, img5;
private volatile float alpha = 1.0f;
private float add = -0.02f;
private Image imgAux;
private Image imagem1, imagem2;

public Efeito2() {

  setSize(800, 600);
  setIgnoreRepaint(true);
  final String endereco[] = new String[5];

  endereco[0] = "/demo/images/imagem1.jpg";
  endereco[1] = "/demo/images/imagem2.jpg";
  endereco[2] = "/demo/images/imagem3.jpg";
  endereco[3] = "/demo/images/imagem4.jpg";
  endereco[4] = "/demo/images/imagem5.jpg";


  img1 = carregarImagem(endereco[0]);
  img2 = carregarImagem(endereco[1]);
  img3 = carregarImagem(endereco[2]);
  img4 = carregarImagem(endereco[3]);
  img5 = carregarImagem(endereco[4]);

  setVisible(true);

  //Iniciamos a thread que fará a imagem se repintar várias vezes
  //Isso dá o efeito de animação.
  Thread t = new Thread(new DemoThread(), "Thread de demonstração");
  t.setDaemon(true);
  t.start();

  contador = new Contador(new Image[]{img1, img2, img3, img4, img5});

  imgAux = contador.next();

  imagem1 = imgAux;

  imagem2 = contador.next();

}

private BufferedImage carregarImagem(String image) {
try {
//Carrega a imagem do disco
BufferedImage img = ImageIO.read(getClass().getResource(image));

     //Converte ela para o formato da tela. Isso aumenta muito as chances do seu desenho ser acelerado por hardware.
     //O processo de covers�o � simples. Simplesmente criamos uma imagem com a configura��o da tela, e desenhamos
     //a imagem carrega sobre esta.
     //Tamb�m j� farei aqui o redimensionamento para o tamanho da tela, evitando gastar tempo com isso na hora de
     //desenhar na tela.
     BufferedImage imagem = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(getWidth(), getHeight(), Transparency.TRANSLUCENT);

     Graphics2D g2d = imagem.createGraphics();
     g2d.drawImage(img, 0, 0, imagem.getWidth(), imagem.getHeight(), 0, 0, img.getWidth(), img.getHeight(), null);
     g2d.dispose();

     //Retornamos a imagem redimensionada e otimizada
     return imagem;
  } catch (IOException e) {
     throw new RuntimeException("Não foi possível carregar a imagem");
  }

}

@Override
public void paint(Graphics g) {

  Graphics2D g2d = (Graphics2D) g.create();
  //Desenhamos a imagem 1
  g2d.drawImage(/*img1*/imagem1, 0, 0, null);

  //Nesta linha, alteramos a transpar�ncia de tudo que ser� desenhado
  //sobre o graphics.
  g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));

  //contador.next();

  //E então desenhamos a imagem 2, sobre a imagem 1.
  g2d.drawImage(/*img2*/imagem2, 0, 0, null);

  //Variamos o alpha
  alpha += add;

  if (alpha < 0.02) {
     add = 0.02f;
  } else if (alpha > 0.98) {
     add = -0.02f;
  }

  g2d.dispose();

}

public class DemoThread implements Runnable {

  @Override
  public void run() {

     try {

        //Para fazer a animação, simplesmente chamamos o repaint várias vezes
        //Essa é uma forma bem rudimentar de animar. O Ponto V! descreve mecanismos
        //melhores.
        while (true) {

           repaint();

           Thread.sleep(1000 / 15); //15 fps

           if (alpha < 0.02 || alpha > 0.98) {

              System.out.println("ENTROU!");

              Thread.sleep(2000);

              imagem1 = imagem2;

              ((Graphics2D) imagem1.getGraphics()).setComposite(AlphaComposite.SrcOver.derive(0.98F));

              imagem2 = contador.next();

              ((Graphics2D) imagem2.getGraphics()).setComposite(AlphaComposite.SrcOver.derive(0.02F));

           }

        }



     } catch (InterruptedException e) {
        //JOptionPane.showMessageDialog(getContentPane(), e);
     }
  }

}

public static void main(String[] args) {
EventQueue.invokeLater(new Runnable() {

     @Override
     public void run() {
        new Efeito2().setVisible(true);
     }
  });

}
}
[/code]

Classe pra mudar as imagens… (esse método next() ai xD):

[code]/*

  • To change this template, choose Tools | Templates
  • and open the template in the editor.
    */
    package demo;

import java.awt.Image;
import java.util.ArrayList;
import java.util.Arrays;
import java.util.Collection;

/**
*

  • @author melissa
    */
    public class Contador {

    private ArrayList imgs;
    private int pointer;

    public Contador(Image[] images) {

    imgs = new ArrayList(Arrays.asList(images));

    pointer = 0;

    System.out.println("Tamanho: " + images.length);

    }

    public Contador(Collection col) {

    imgs = new ArrayList(col);

    pointer = 0;

    }

    public Image next() {

    if (pointer >= imgs.size()) {
    pointer = 0;
    }

    Image next = imgs.get(pointer);

    System.out.println(“next(): " + next.toString() + " (” + pointer + “)”);

    pointer++;

    return next;

    }
    }[/code]

Alguma idéia?

Oi.

Só um comentário, antes de entrar no problema mesmo. Sempre que você sobrescreve um componente (como nesse caso), você deve sobrescrever o método paintComponent e não o paint.

O paint em componentes faz mais coisas do que simplesmente pinta-lo na tela, e você pode ter um comportamento inconveniente se sobrescreve-lo. A parte encarregada só do componente em si fica no paintComponent.

Ops! Arrumei já. ^^

[code]@Override
public void paintComponent(Graphics g) {

  Graphics2D g2d = (Graphics2D) g.create();
  //Desenhamos a imagem 1
  g2d.drawImage(/*img1*/imagem1, 0, 0, null);

  //Nesta linha, alteramos a transpar&#65533;ncia de tudo que ser&#65533; desenhado
  //sobre o graphics.
  g2d.setComposite(AlphaComposite.SrcOver.derive(alpha));

  //contador.next();

  //E então desenhamos a imagem 2, sobre a imagem 1.
  g2d.drawImage(/*img2*/imagem2, 0, 0, null);

  //Variamos o alpha
  alpha += add;

  if (alpha &lt; 0.02) {
     add = 0.02f;
  } else if (alpha &gt; 0.98) {
     add = -0.02f;
  }

  g2d.dispose();

}[/code]

Mas não mudou muita coisa ‘-’

Não, não tinha muito a ver com o problema. Na verdade, essa é uma daquelas coisas que se der erro, é só de vez enquanto.
O mesmo vale para o tipo de manipulação que você fez dentro do “run” da thread.

Infelizmente não estou com muito tempo para te mostrar como evitar o flickering. =/

O problema é que nem é flickering… (eu tinha dado uma olhada no ponto V! sobre isso) é que ele ta chamando a próxima imagem e desbotando ela, ao invés de desbotar a anterior

Hey people! xD

Meu problema mudou ‘-’ com uma ajuda aqui a gente refez essa parte que tava com problema, e agora ela funciona ^^ Problema agora é diferente:

1-A imagem perde qualidade .-.

2-A imagem tá crescendo sozinha o.O

O código tá aqui se alguém quiser olhar… (não sei se serve pra alguma coisa porque to fazendo no FreeDesign)

[code]package demo;

import java.awt.Graphics2D;
import java.awt.GraphicsEnvironment;
import java.awt.Image;
import java.awt.Transparency;
import java.awt.image.BufferedImage;
import java.io.IOException;
import java.util.Collection;
import java.util.logging.Level;
import java.util.logging.Logger;
import javax.imageio.ImageIO;
import javax.swing.ImageIcon;
import javax.swing.JFrame;

public class FrameTeste extends javax.swing.JFrame {

private Image[] images;
private float alpha = 1.0F;
private int pointer = 0;
private int tempoExibicao = 3000;
private int framesPerSecond = 1000 / 15;
private float alphaTax = 0.02F;
private Image curr;

public FrameTeste() {

  initComponents();
  labelImagem.setSize(panelImg.getSize());

  setExtendedState(JFrame.MAXIMIZED_BOTH);

  final String endereco[] = new String[5];

  images = new Image[5];

  endereco[0] = "/demo/images/imagem1.jpg";
  endereco[1] = "/demo/images/imagem2.jpg";
  endereco[2] = "/demo/images/imagem3.jpg";
  endereco[3] = "/demo/images/imagem4.jpg";
  endereco[4] = "/demo/images/imagem5.jpg";

  images[0] = carregarImagem(endereco[0]);
  images[1] = carregarImagem(endereco[1]);
  images[2] = carregarImagem(endereco[2]);
  images[3] = carregarImagem(endereco[3]);
  images[4] = carregarImagem(endereco[4]);

  initTimer();

}

public FrameTeste(Collection imgs) {

  initComponents();

  images = imgs.toArray(new Image[]{});

}

private void initTimer() {

  new Thread() {

     @Override
     public void run() {

        try {
           Thread.sleep(1000);
        } catch (InterruptedException ex) {
           Logger.getLogger(FrameTeste.class.getName()).log(Level.SEVERE, null, ex);
        }

        while (true) {

           labelImagem.setSize(panelImg.getSize());

           curr = getNext();

           System.out.println("Largura: " + labelImagem.getWidth() + ", Altura: " + labelImagem.getHeight());

           labelImagem.setIcon(new ImageIcon(curr.getScaledInstance(labelImagem.getWidth(), labelImagem.getHeight(), 0)));

           while (alpha > 0.0F) {

              panelImg.setAlpha(alpha);

              try {
                 Thread.sleep(framesPerSecond);
              } catch (InterruptedException ex) {
                 Logger.getLogger(FrameTeste.class.getName()).log(Level.SEVERE, null, ex);
              }

              alpha -= alphaTax;

           }

           alpha = 0.0F;

           System.out.println("Alpha: " + alpha);

           curr = getNext();

           System.out.println("Largura: " + labelImagem.getWidth() + ", Altura: " + labelImagem.getHeight());

           labelImagem.setIcon(new ImageIcon(curr.getScaledInstance(labelImagem.getWidth(), labelImagem.getHeight(), 0)));

           panelImg.setAlpha(alpha);

           while (alpha < 1.0F) {

              panelImg.setAlpha(alpha);

              try {
                 Thread.sleep(framesPerSecond);
              } catch (InterruptedException ex) {
                 Logger.getLogger(FrameTeste.class.getName()).log(Level.SEVERE, null, ex);
              }

              alpha += alphaTax;

           }

           alpha = 1.0F;

           System.out.println("Alpha: " + alpha);

           try {
              Thread.sleep(tempoExibicao);
           } catch (InterruptedException ex) {
              Logger.getLogger(FrameTeste.class.getName()).log(Level.SEVERE, null, ex);
           }

           while (alpha > 0.0F) {

              panelImg.setAlpha(alpha);

              try {
                 Thread.sleep(framesPerSecond);
              } catch (InterruptedException ex) {
                 Logger.getLogger(FrameTeste.class.getName()).log(Level.SEVERE, null, ex);
              }

              alpha -= alphaTax;

           }

           alpha = 0.0F;

           System.out.println("Alpha: " + alpha);

        }

     }
  }.start();

}

/** This method is called from within the constructor to
* initialize the form.
* WARNING: Do NOT modify this code. The content of this method is
* always regenerated by the Form Editor.
*/
@SuppressWarnings(“unchecked”)
//
private void initComponents() {

  panelImg = new org.jdesktop.swingx.JXImagePanel();
  labelImagem = new org.jdesktop.swingx.JXLabel();

  setDefaultCloseOperation(javax.swing.WindowConstants.EXIT_ON_CLOSE);

  panelImg.setBorder(javax.swing.BorderFactory.createEtchedBorder());
  panelImg.setMaximumSize(new java.awt.Dimension(1024, 768));
  panelImg.setPreferredSize(new java.awt.Dimension(600, 480));

  labelImagem.setBorder(javax.swing.BorderFactory.createEtchedBorder());

  javax.swing.GroupLayout panelImgLayout = new javax.swing.GroupLayout(panelImg);
  panelImg.setLayout(panelImgLayout);
  panelImgLayout.setHorizontalGroup(
     panelImgLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
     .addGroup(panelImgLayout.createSequentialGroup()
        .addContainerGap()
        .addComponent(labelImagem, javax.swing.GroupLayout.DEFAULT_SIZE, 1472, Short.MAX_VALUE)
        .addContainerGap())
  );
  panelImgLayout.setVerticalGroup(
     panelImgLayout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
     .addGroup(panelImgLayout.createSequentialGroup()
        .addContainerGap()
        .addComponent(labelImagem, javax.swing.GroupLayout.DEFAULT_SIZE, 1472, Short.MAX_VALUE)
        .addContainerGap())
  );

  javax.swing.GroupLayout layout = new javax.swing.GroupLayout(getContentPane());
  getContentPane().setLayout(layout);
  layout.setHorizontalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
     .addComponent(panelImg, javax.swing.GroupLayout.DEFAULT_SIZE, 1500, Short.MAX_VALUE)
  );
  layout.setVerticalGroup(
     layout.createParallelGroup(javax.swing.GroupLayout.Alignment.LEADING)
     .addComponent(panelImg, javax.swing.GroupLayout.DEFAULT_SIZE, 1500, Short.MAX_VALUE)
  );

  pack();

}//

/**
* @param args the command line arguments
*/
public static void main(String args[]) {

  java.awt.EventQueue.invokeLater(new Runnable() {

     public void run() {
        new FrameTeste().setVisible(true);
     }
  });

}
// Variables declaration - do not modify
private org.jdesktop.swingx.JXLabel labelImagem;
private org.jdesktop.swingx.JXImagePanel panelImg;
// End of variables declaration

private BufferedImage carregarImagem(String image) {

  try {
    
     BufferedImage img = ImageIO.read(getClass().getResource(image));

     BufferedImage imagem = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(getWidth(), getHeight(), Transparency.TRANSLUCENT);

     Graphics2D g2d = imagem.createGraphics();
     g2d.drawImage(img, 0, 0, imagem.getWidth(), imagem.getHeight(), 0, 0, img.getWidth(), img.getHeight(), null);
     g2d.dispose();

     return img;

  } catch (IOException e) {

     throw new RuntimeException("Não foi possível carregar a imagem");

  }

}

private Image getNext() {

  System.out.println("Pointer: " + pointer);

  Image i = images[pointer];

  pointer++;

  if (pointer >= images.length) {

     pointer = 0;

  }

  return i;

}
}[/code]

Alguma idéia? Ou melhor, alguma coisa que eu deixei passar e não vi? XD

vlw! ^^

Quanto a imagem crescer sozinha, leia os comentários da linha 70. :wink:

Quanto à imagem perder qualidade, é porque você usa jpg. E os algorítmos de jpg do Java usam um nível muito agressivo de compactação. Aqui mostra como evitar tanta compactação:
http://www.universalwebservices.net/web-programming-resources/java/adjust-jpeg-image-compression-quality-when-saving-images-in-java

E aqui mostra como definir os rendering hints do Graphics2D para priorizar qualidade ao invés de performance:
http://download.oracle.com/javase/tutorial/2d/advanced/quality.html

Cuidado que existe um erro muitíssimo grave no seu código. Você está fazendo atualizações nos componentes gráficos por fora da Thread do Swing. O método run() ali deveria somente conter o comando de repaint.

Para entender melhor sobre isso:
http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html
http://java.sun.com/products/jfc/tsc/articles/painting/#swing

Se você persistir nesse erro, sua aplicação pode dar crashes inesperados, ou simplesmente não funcionar em todos os computadores. O Swing não é Thread-safe, e não pode ser manipulado por mais de uma Thread simultânea, além da dele mesmo.

Isso que tem na linha 70 o.o

[code]@Override
public void run() {

        try {  
           Thread.sleep(1000);  //Linha 70 xD
        } catch (InterruptedException ex) {  
           Logger.getLogger(FrameTeste.class.getName()).log(Level.SEVERE, null, ex);  
        }  [/code]

Valeu vini! Vou dar uma olhada! ^^

[quote=ViniGodoy]Cuidado que existe um erro muitíssimo grave no seu código. Você está fazendo atualizações nos componentes gráficos por fora da Thread do Swing. O método run() ali deveria somente conter o comando de repaint.

Para entender melhor sobre isso:
http://java.sun.com/products/jfc/tsc/articles/threads/threads1.html
http://java.sun.com/products/jfc/tsc/articles/painting/#swing

Se você persistir nesse erro, sua aplicação pode dar crashes inesperados, ou simplesmente não funcionar em todos os computadores. O Swing não é Thread-safe, e não pode ser manipulado por mais de uma Thread simultânea, além da dele mesmo.[/quote]

Opa! Vou dar um jeito nisso! ^^

Ops, desculpe, era do código que você abriu o tópico:

//Também já farei aqui o redimensionamento para o tamanho da tela, evitando gastar tempo com isso na hora de //desenhar na tela.

Como seu código ainda está igual ao meu, ele ainda está redimensionando.

Você pode alterar o carregar imagem para:

[code]private BufferedImage carregarImagem(String image) {
try {
BufferedImage img = ImageIO.read(getClass().getResource(image));
BufferedImage imagem = GraphicsEnvironment.getLocalGraphicsEnvironment().getDefaultScreenDevice().getDefaultConfiguration().createCompatibleImage(img.getWidth(), img.getHeight(), Transparency.TRANSLUCENT);
Graphics2D g2d = imagem.createGraphics();
g2d.drawImage(img, 0, 0, null);
g2d.dispose();

  return img;  

} catch (IOException e) {
throw new RuntimeException(“Não foi possível carregar a imagem”, e);
}
} [/code]

Ah ta xD

Troquei, mas não adiantou ‘-’

Olha a saída do tamanho:

run: Pointer: 0 Largura: 1280, Altura: 647 Alpha: 0.0 Pointer: 1 Largura: 1284, Altura: 651 Alpha: 1.0 Alpha: 0.0 Pointer: 2 Largura: 1316, Altura: 683 Alpha: 0.0 Pointer: 3 Largura: 1316, Altura: 683 Alpha: 1.0 Alpha: 0.0 Pointer: 4 Largura: 1348, Altura: 715 Alpha: 0.0 Pointer: 5 Largura: 1348, Altura: 715 Alpha: 1.0 Alpha: 0.0 Pointer: 0 Largura: 1380, Altura: 747 Alpha: 0.0 Pointer: 1 Largura: 1380, Altura: 747 Alpha: 1.0 Alpha: 0.0 Pointer: 2 Largura: 1412, Altura: 779 Alpha: 0.0 Pointer: 3 Largura: 1412, Altura: 779 BUILD SUCCESSFUL (total time: 49 seconds)

Continua crescendo sozinha ‘-’

Descobri porque a imagem estava crescendo sozinha…FreeDesign tava me zoando xD troquei para BorderLayout e problema resolvido ^^