[Resolvido] Imagem mal renderizada

9 respostas
jubapunx

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:
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;
    }

9 Respostas

jubapunx

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

ViniGodoy

E como você codifica a imagem?

jubapunx
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;
    }

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

Tipo:

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

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.

jubapunx

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

Classe "Comunicacao" do Cliente:

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

}

Classe "Comunicação" do Servidor:

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

}

Classe "Conexao" do Servidor:

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

}
ViniGodoy

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?

jubapunx

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).

jubapunx

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

jubapunx

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’.

Criado 20 de setembro de 2013
Ultima resposta 26 de set. de 2013
Respostas 9
Participantes 2