[Resolvido] Imagem mal renderizada

Olá, estou “encodando” imagens para B64 e enviando elas como String para o cliente (socket). Só que quando a imagem é remontado no cliente, ela fica tudo bugada. Alguém sabe o que pode ser?

Informações: BufferedImage imagem = Imagem.decodificarParaImagem(infos.get(i + 1)); JLabel rotFoto = new JLabel(new ImageIcon(imagem.getScaledInstance(94, 94, java.awt.Image.SCALE_SMOOTH))); rotFoto.setBounds(10, yPos, 94, 94);

infos.get(i + 1) = http://pt.scribd.com/doc/169634928/aimagem-txt

Já estou ficando realmente puto com isso, nunca pedi ajuda em fóruns e esse problema tá me dando dor de cabeça hein! Já tive que mudar a estrutura base do programa algumas vezes, e mesmo assim ainda não consegui resolver o erro.

Ah, e o método “decodificarParaImagem” é esse: [code] public static BufferedImage decodificarParaImagem(String imageString) {

    BufferedImage image = null;
    byte[] imageByte;
    try {
        Base64 decoder = new Base64();
        imageByte = decoder.decode(imageString);
        ByteArrayInputStream bis = new ByteArrayInputStream(imageByte);
        image = ImageIO.read(bis);
        bis.close();
    } catch (Exception e) {
        e.printStackTrace();
    }
    return image;
}[/code]

E é assim que a imagem fica: http://imgup.com/data/images/4109.png

E como você codifica a imagem?

[code] public static String codificarParaString(BufferedImage imagem, String tipo) {
String imagemString = null;
ByteArrayOutputStream saidaInfo = new ByteArrayOutputStream();

    try {
        ImageIO.write(imagem, tipo, saidaInfo);
        
        byte[] imagemBytes = saidaInfo.toByteArray();

        Base64 codificador = new Base64();
        imagemString = codificador.encodeAsString(imagemBytes);

        saidaInfo.close();
    } catch (IOException e) {
        e.printStackTrace();
    }
    return imagemString;
}[/code]

também tô achando que pode ser erro de sincronia com socket, já que estou usando um timer para fazer o filtro…

Tipo:

[code] private void m(){
Timer t = new Timer();

	t.schedule(new TimerTask() {
		int tInicial = 0;
		public void run() {
			if(tInicial != texBuscar.getText().length()){
				//enviar pacote de busca pro servidor
				//obter resposta do servidor
				//popular panel com as imagens das buscas (limite 0, 30)
				tInicial = texBuscar.getText().length();
			}
		}
	}, 1, 1);
}[/code]

Se está usando sockets direto, porque está transmitindo a imagem numa forma tão ineficiente quanto String? Não era mais fácil usar um protocolo binário?

Parece ser mesmo um problema da sua comunicação. Teria que ver como você está fazendo a leitura e a escrita do socket.

Já tentou usar esse método de codificar e decodificar num programa local, sem o socket no meio? Assim pelo menos você descobre se os dois métodos estão implementados corretamente, ou se é problema da transmissão.

Eu andei modificando o cliente, então pode não estar exatamente do jeito que estava antes, mas é assim:

Classe “Comunicacao” do Cliente:

[code]package com.zmeck_c.tcp;

import java.io.BufferedReader;
import java.io.BufferedWriter;
import java.io.IOException;
import java.io.InputStreamReader;
import java.io.OutputStreamWriter;
import java.net.Socket;
import java.net.SocketException;

import com.zmeck_c.Principal;
import com.zmeck_c.util.Ig;

public class Comunicacao {

public static String pegarPacote(Socket sock){
	String pac = "";
	try{
		BufferedReader leitorBuffer = new BufferedReader(new InputStreamReader(sock.getInputStream()));
		
		while(true){
			char[] next = new char[10000];
			int tamanho = leitorBuffer.read(next);
			
			String proximo = "";
			for(int i = 0; i < tamanho; i++){
				proximo += next[i];
			}
			pac += proximo;
			
			if(proximo.charAt(proximo.length() - 1) == (char)2){
				pac = pac.substring(0, pac.length() - 1);
				break;
			}
		}
	}
	catch(SocketException e){
		Ig.mensagemAlerta("Você foi desconectado. Tente se conectar novamente.");
		System.exit(0);
	} catch (IOException e) {
		e.printStackTrace();
	}
	return pac;
}

public static void enviarPacote(String pacote){
	try{
		//BufferedWriter escritorBuffer = new BufferedWriter(new OutputStreamWriter(Principal.S.getOutputStream()));
		int t = 0;
		int paclen = pacote.length();
		boolean quebra = false;
		for(int i = 0; i < paclen; i++){
			for(int m = 0; m < 10000; m++){
				if(pacote.length() < 10000){
					BufferedWriter escritorBuffer = new BufferedWriter(new OutputStreamWriter(Principal.S.getOutputStream()));
					escritorBuffer.write(pacote + (char)2);
					escritorBuffer.flush();
					t = t + 10000;
					quebra = true;
					System.out.println("FLUSH");
					break;
				}
				else{
					String proximo = pacote.substring(0, 10000);
					pacote = pacote.substring(10000, pacote.length());
					
					BufferedWriter escritorBuffer = new BufferedWriter(new OutputStreamWriter(Principal.S.getOutputStream()));
					escritorBuffer.write(proximo);
					escritorBuffer.flush();
					t = t + 10000;
					//System.out.println(t + "            " + paclen + "          " + pacote.length());
				}
			}
			if(quebra == true){
				break;
			}
		}
	}
	catch (IOException e){
		
	}
	System.out.println("FUCK");
}

}
[/code]

Classe “Comunicação” do Servidor:

[code]package com.zmeck_s.tcp;

import java.io.BufferedWriter;
import java.io.IOException;
import java.io.OutputStreamWriter;

public class Comunicacao {

public static void enviarPacote(int idConexao, String pacote){
	//System.out.println("[SERVIDOR] enviou para [" + idConexao + "]: " + pacote);
	
	if(FabricaConexoes.conexoesArmazenadas.get(idConexao).pegarConectado()){
		try{
			//BufferedWriter escritorBuffer = new BufferedWriter(new OutputStreamWriter(Principal.S.getOutputStream()));
			int t = 0;
			int paclen = pacote.length();
			boolean quebra = false;
			for(int i = 0; i < paclen; i++){
				for(int m = 0; m < 10000; m++){
					if(pacote.length() < 10000){
						BufferedWriter escritorBuffers = new BufferedWriter(new OutputStreamWriter(FabricaConexoes.conexoesArmazenadas.get(idConexao).pegarFluxoDados().getOutputStream()));
						escritorBuffers.write(pacote + (char)2);
						escritorBuffers.flush();
						System.out.println("SERVIDOR >> " + pacote + (char)2);
						t = t + 10000;
						quebra = true;
						//System.out.println("enviado");
						break;
					}
					else{
						String proximo = pacote.substring(0, 10000);
						pacote = pacote.substring(10000, pacote.length());
						
						BufferedWriter escritorBuffers = new BufferedWriter(new OutputStreamWriter(FabricaConexoes.conexoesArmazenadas.get(idConexao).pegarFluxoDados().getOutputStream()));
						escritorBuffers.write(proximo);
						escritorBuffers.flush();
						System.out.println("SERVIDOR >> " + proximo);
						//System.out.println("enviado");
						t = t + 10000;
					}
				}
				if(quebra == true){
					break;
				}
			}
		}
		catch (IOException e){
			
		}
	}
}

public static void enviarPacoteTodos(String pacote){
	int nConexoes = FabricaConexoes.conexoesArmazenadas.size();
	for(int i = 0; i < nConexoes; i++){
		try {
			System.out.println("[SERVIDOR] enviou para [" + FabricaConexoes.conexoesArmazenadas.get(i).pegarIdConexao() + "]: " + pacote);
			
			if(FabricaConexoes.conexoesArmazenadas.get(i).pegarConectado()){
				BufferedWriter escritorBuffers = new BufferedWriter(new OutputStreamWriter(FabricaConexoes.conexoesArmazenadas.get(i).pegarFluxoDados().getOutputStream()));
				escritorBuffers.write(pacote);
				escritorBuffers.flush();
			}
		} catch (IOException e) {
			e.printStackTrace();
		}
	}
}

}
[/code]

Classe “Conexao” do Servidor:

[code]package com.zmeck_s.tcp;

import java.io.BufferedReader;
import java.io.IOException;
import java.io.InputStreamReader;
import java.net.Socket;
import java.net.SocketException;
import java.util.ArrayList;

import com.zmeck_s.Principal;
import com.zmeck_s.util.Escritor;

public class Conexao extends Thread {

private Socket fluxoDados = null;
private int idConexao = -1;
private String enderecoIp = null;
private boolean conectado = false;

private int idLogin = 0;

public Conexao(Socket fluxoDados, int idConexao, String enderecoIp){
	this.fluxoDados = fluxoDados;
	this.idConexao = idConexao;
	this.enderecoIp = enderecoIp;
	
	FabricaConexoes.contagemConexoes++;
	
	start();
	
	System.out.println("[!] Nova conexao: [IP: " + enderecoIp + "]-[ID: " + idConexao + "]");
	setarConectado(true);
}

public void run() {
	while(fluxoDados.isConnected()){
		try {
			BufferedReader leitorBuffer = new BufferedReader(new InputStreamReader(fluxoDados.getInputStream()));
			
			String pac = "";
			while(true){
				//System.out.println("here");
				char[] next = new char[10000];
				int tamanho = leitorBuffer.read(next);
				
				String proximo = "";
				for(int x = 0; x < tamanho; x++){
					proximo += next[x];
				}
				pac += proximo;
				
				if(proximo.charAt(proximo.length() - 1) == (char)2){
					break;
				}
			}
			ArrayList<String> pacotes = Escritor.separar(pac, (char)2);
			
			for(int i = 0; i < pacotes.size(); i++){
				Tratamento.tratamento(idConexao, pacotes.get(i));
			}
			
		}
		catch (SocketException e){
			interrupt();
			System.out.println("Conexao: " + enderecoIp + "-" + idConexao + " perdida. (SocketException).");
			FabricaConexoes.contagemConexoes--;
			setarConectado(false);
			Principal.CLIENTES.get(idLogin).setarConectado(false);
			
			break;
		}
		catch (IOException e) {
			interrupt();
			System.out.println("Conexao: " + enderecoIp + "-" + idConexao + " perdida. (IOException).");
			FabricaConexoes.contagemConexoes--;
			setarConectado(false);
			Principal.CLIENTES.get(idLogin).setarConectado(false);
			
			break;
		}
	}
}

public Socket pegarFluxoDados(){
	return fluxoDados;
}

public int pegarIdConexao(){
	return idConexao;
}

public String pegarEnderecoIp(){
	return enderecoIp;
}

public void setarIDLogin(int idLogin){
	this.idLogin = idLogin;
}

public int pegarIDLogin(){
	return idLogin;
}

public void setarConectado(boolean conectado){
	this.conectado = conectado;
}

public boolean pegarConectado(){
	return conectado;
}

public void desconectar(){
	try {
		fluxoDados.shutdownInput();
		Comunicacao.enviarPacote(idConexao, "Buzzy ;D");
	} catch (IOException e) {
		e.printStackTrace();
	}
}

}
[/code]

O método Base64 codifica a String usando UTF-8 como encoding. Você se certificou que as demais Strings do seu programa usam o mesmo encoding?

Não… Na realidade nunca tinha verificado ou usado algum tipo de “encoding”.

Eu suspeito que o erro é na transmissão da informação, porque Na primeira parte dá certo, aparece a imagem do perfil, porém quando eu tento fazer pelo filtro é que dá erro (que é quando eu uso o Timer, que é assíncrono).

Eu já usei os métodos em um programa local, tudo ok.

Vou tentar resolver o erro mais tarde, aí posto qual a solução que eu usei. Mas com certeza é problema na transmissão de dados. Realmente deve ser a assincronia do Timer e do Socket, usando os dois juntos ainda, aí que deve ter dado problema. xD

Finalmente arranjei tempo para trabalhar em cima do projeto e consegui resolver o erro! :smiley:

Ao invés de enviar de 10 mil em 10 mil caracteres para o servidor e identificar o final do pacote por um (char)2, eu voltei a fazer como antigamente, enviar tudo de uma vez só.

sock.write(pacote) sock.flush();

O resto é só lógica de programação, como redimensionar as imagens antes de envia-las ao servidor e usar JPG ao invés do pesado PNG. xD

Obrigadão aê ViniGodoy. Você é professor na PUC daqui de Curitiba né? Já invadi uma sala lá pra ajudar aluno em prova de programação, mas não na sua matéria kkkkk’.