Salvar um objeto Image

Senhores, estou necessitando salvar um objeto Image no sistema de arquivo.

Para tal estou agindo da seguinte forma:

  1. chamo o método

public static final byte[] getImageByteArray(Image image) { int raw[] = new int[image.getWidth() * image.getHeight()]; image.getRGB(raw, 0, image.getWidth(), 0, 0, image.getWidth(), image.getHeight()); byte rawByte[] = new byte[image.getWidth() * image.getHeight() * 4]; int n = 0; // for(int i = 0; i < raw.length; i++) { int ARGB = raw[i]; int a = (ARGB & 0xff000000) >> 24; int r = (ARGB & 0xff0000) >> 16; int g = (ARGB & 0xff00) >> 8; int b = ARGB & 0xff; rawByte[n] = (byte)b; rawByte[n + 1] = (byte)g; rawByte[n + 2] = (byte)r; rawByte[n + 3] = (byte)a; n += 4; } // raw = null; // return rawByte; }

que é responsavel por serealizar o meu objeto Image.

Só que quando vou abrir o arquivo gerado a imagem não está visível. Me falaram que eu tenho que utilizar algum algoritmo de compressão de imagem para a imagem poder ser lida. corretamente. Algum conhece alguma API que faça isso ou outra forma de persistir um Image.

Caro André,

O procedimento de tranformar a imagem em byte[] está correto. No entanto, seria bom se você postasse aqui o código que salva a imagem, e o código que carrega a imagem salva.

Abraço,

Vai salvar sua imagem utilizando a compactação JPEG, existem outros formatos dá uma olhada no JavaDocs de ImageIO


ImageIO.write(suaImagemEmJava ,  "jpeg" , new File("c:\minhaImagem.jpg") ) ;

No caso a leitura deve ser realizada por qualquer programa de leitura de arquivos. O código de escrita é o seguinte:

[code]public void writeFile( final String device, final byte[] b ) throws GiftException{

 new Thread(new Runnable(){
	 
	 public void run(){
		OutputStream streamOutPut = null;
		// 
		try {
			//Create file
			FileConnection fileSystem = (FileConnection)Connector.open( device,Connector.READ_WRITE );
			//
			if(!fileSystem.exists()) {
				fileSystem.create();
			}
			//
			//Save file
			streamOutPut = fileSystem.openOutputStream();
			//
			streamOutPut.write(b);
			//
			streamOutPut.flush();
			//
			streamOutPut.close();
			//
		} catch (IOException e) {
			e.printStackTrace();
		}finally {
			if (streamOutPut != null) {
				//
				try {
					streamOutPut.close();
				} catch (IOException e) {
				}
			}
		}
	 }
 }).start();

}[/code]

Amigo, o que você está tentando fazer só é possível com bibliotecas de encodding PNG à parte.

Analise: Você pega todos os pixels num byte[]. Grava esses bytes num arquivo. No entanto, esse arquivo nada mais é do que um vetor de bytes! Ele não está no formato de imagem PNG, JPG, GIF… Entende?

Se você quiser que essa imagem seja recuperada pela própria aplicação no aparelho, não há problemas, pois a aplicação no aparelho lerá o vetor de bytes do arquivo, e criará a imagem usando as ifnormações dos pixels, e não informações de bytes de um arquivo codificado em Imagem. Mas dessa forma, nenhum vizualizador de imagens conseguiria ler o arquivo, apenas a sua aplicação, pois só ela sabe que aquele arquivo deve ser lido como vetor de bytes.

Se realmente você precisa gravar em formato de imagem codificado, use bibliotecas que fazem o papel de transformar um RGB[] em imagem codificada.

Sei que existe essa classe. O uso é bem simples:
http://www.chrfr.de/software/midp_png.html

Abraço

Caro Nelson,

a classe que você me indico funcionou perfeitamente.

Muito Obrigado

Cara Andre.

Encontrei sua conversa com o Pereira e gostaria de um esclarecimento.
Estou comecando a programar com j2me e estou meio confuso ainda.
Eu preciso salvar uma imagem para posterior uso. Pelo que vi, a classe
do Christian Fröschlin funcionou para voce. Eu nao entendi, no entando,
como a classe salva a imagem. Eu entendi errado, ou a imagem e’ escrita
para uma instancia da classe ByteArrayOutputStream, que permanece
apenas na memoria? Eu gostaria de grava-la no sistema de arquivo do
celular.
Como voce fez isso? Outra pergunta, e’ possivel acessar o sistema de
diretorio do celular e voce sabe como fazer isso?
Agradeco desde ja qq ajuda.
Ricardo

Ricardo

da uma olhada nesse link ele te explica como usar a classe Connector

http://web.mit.edu/bentley/www/mobile/j2meguide/

nele você descobre desde como ler e escrever em um arquivo até eviar um sms.

Uma resalva quanto o código citado anteriormente, ele funciona para imagens pequenas.
No momento eu to utilizando uma outra classe que realiza o encoder no formato JPÈG.

Uma abraço mestre Ricardo

Galera é o seguinte, preciso salvar uma imagem que foi feito um tratamento em cima dela. Mas como o pessoal disse que é necessário de alguma classe que faça o encording para a extensão desejada(PNG,JPG)…então estou utilizando a classe PNG que npereirajr indicou…porem não consigo fazer funciona!!

Ele salva o .png mas não abre no celular,entao o arquivo não está em formato PNG ainda!

Por favor dêem uma olhada no código e vejam se há algo de errado!!

Aqui é onde eu transformo a imagem em um vetor de bytes(PNG).

 public byte[] getBytePNG(Image image) {  
      int[] raw = new int[image.getWidth() * image.getHeight()];
      image.getRGB(raw, 0, image.getWidth(), 0, 0, image.getWidth(), image.getHeight());
      int a,r,g,b;
      byte[] vetByte = null;
      byte[] aV  = new byte[raw.length];
      byte[] rV =  new byte[raw.length];
      byte[] gV =  new byte[raw.length];
      byte[] bV =  new byte[raw.length];
        try {        
            //
            for (int i = 0; i < raw.length; i++) {
                int ARGB = raw[i];
                a =  ((ARGB & 0xff000000) >> 24);
                r =  ((ARGB & 0xff0000) >> 16);
                g =  ((ARGB & 0xff00) >> 8);
                b =  ( ARGB & 0xff);
                aV[i]= (byte)a;
                rV[i]= (byte)r;
                gV[i]= (byte)g;
                bV[i]= (byte)b;       
            }
            //
            raw = null;     
            vetByte = PNG.toPNG(image.getWidth(), image.getHeight(),aV,rV,gV,bV);  
        } catch (IOException ex) {
            ex.printStackTrace();

Esse são os parametros da função .toPNG da classe PNG


public static byte[] toPNG(int width, int height, byte[] alpha, byte[] red, byte[] green, byte[] blue) throws IOException

Aqui é onde eu salvo a imagem no sistema de arquivos do celular.

  public void saveFilePNG(){
      new Thread(new Runnable() {
               public void run() {             
                try{
                    FileConnection sc = (FileConnection)Connector.open("file://localhost/SD/"+arq+".png");
                    
                    sc.create();
                    
                    OutputStream os = sc.openOutputStream();
                    
                    os.write(finalImage,0,finalImage.length);
                    
                    os.flush();
                    
                    os.close();
                   }
                    catch(Exception e){
                  }
            
               }
           }).start();          
    }

Obrigado!

 Cara a classe PNG que o nosso amigo indico ela possui uma limitação quanto o tamanho do array do bytes. Por esse motivo eu procurei uma classe JPEGEncoder ou BMPEncoder.

nesse mesmo caminho,
eu consigo copiar uma imagem contida no pacote para o celular do usuario???