Imagens com Qualidade Ruim

26 respostas
laelsonc

Galera, to com um problema que não sei mais o que fazer. Tenho um gerenciador de galeria de fotos. Tô usando um método para redimensionar as fotos e adicionar uma marca dágua, só que ele tem dois problemas: QUALIDADE RUIM DOS THUMBS E CONSOME MUITA MEMÓRIA.
O mais sério é a QUALIDADE, que meus clientes reclamam demais. Alguém tem um método show de bola ai não ?

Segue os métodos:

public static void gerarThumbnail(InputStream inputStream, OutputStream out, int thumbAltura, int thumbLargura, float quality) throws Exception{

            Image image = null;
            int largura = 0;
            int altura = 0;


            try {
            //Recuperar os valores de LARGURA/ALTURA e ALTERAR no registro da FOTO
            image = ImageIO.read(inputStream);
            largura = image.getWidth(null);
            altura = image.getHeight(null);
            
            
            
            } catch (Exception e) {
            throw new Exception("ERRO ALTERANDO TAMANHO DA IMAGEM " + e);
            }

            try {

            //Fazer a geracao do TumbNail levando em conta o tamanho da ALTURA
            MediaTracker mediaTracker = new MediaTracker(new Container());
            mediaTracker.addImage(image, 0);
            mediaTracker.waitForID(0);

            // determine thumbnail size from WIDTH and HEIGHT
            double thumbPorcentagem;
            
            if(thumbLargura == 0){
                thumbPorcentagem = ((thumbAltura*100.0)/altura)/100.0;

                if(thumbLargura == 0){
                thumbLargura = (int)(largura * thumbPorcentagem);
                }
            }

            if(thumbAltura == 0){
                thumbPorcentagem = ((thumbLargura*100.0)/largura)/100.0;

                if(thumbAltura == 0){
                thumbAltura = (int)(altura * thumbPorcentagem);
                }
            }            
            
            // draw original image to thumbnail image object and
            // scale it to the new size on-the-fly
            BufferedImage thumbImage = new BufferedImage(thumbLargura,thumbAltura, BufferedImage.TYPE_INT_RGB);
            Graphics2D graphics2D = thumbImage.createGraphics();
            graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,RenderingHints.VALUE_INTERPOLATION_BILINEAR); //VALUE_INTERPOLATION_BICUBIC - For speed better use RenderingHints.VALUE_INTERPOLATION_BILINEAR
            
            graphics2D.drawImage(image, 0, 0, thumbLargura, thumbAltura, null);
            graphics2D.dispose();
            
            // save thumbnail image to OUTFILE
            JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
            JPEGEncodeParam param = encoder.getDefaultJPEGEncodeParam(thumbImage);

            param.setQuality(quality, false); //The quality argument from the command line is converted from the interval 0 to 100 to the interval 0.0f to 1.0f, because that's what the codec expects (I mostly use 0.75f).
            encoder.setJPEGEncodeParam(param);
            encoder.encode(thumbImage);
            
            /* ALTERAÇÕES EM  26/12/2008 */
            graphics2D.dispose();
            image.flush();
            thumbImage.flush();
            /* ------------------------------------ */
            
            inputStream.close();
            out.flush();
            out.close();
            

            } catch (Exception e) {
            throw new Exception("ERRO SALVANDO O THUMBNAIL DA IMAGEM " + e);
            }
            }

            public static void gerarWatermark(InputStream imagemOriginal, InputStream imagemWatermark, OutputStream imagemGerada,String posicao,float alpha){

            try {

            BufferedImage im = ImageIO.read(imagemOriginal);
            BufferedImage im2 = ImageIO.read(imagemWatermark);
            Graphics2D g = im.createGraphics();            
            g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, alpha));
            
            
            //g.drawImage(im2, (im.getWidth()-im2.getWidth())/2, (im.getHeight()-im2.getHeight())/2, null);
            
                       
            // TOP ESQUERDO 
            if(posicao.equals("7")){
            g.drawImage(im2, 0, 0, null); 
                        
            // TOP CENTRO
            }else if(posicao.equals("8")){
            g.drawImage(im2, (im.getWidth()-im2.getWidth())/2, 0, null); 
                        
            // TOP DIREITO
            }else if(posicao.equals("9")){
            g.drawImage(im2, (im.getWidth()-im2.getWidth()), 0, null); 
                        
            // CENTRO ESQUERDO
            }else if(posicao.equals("4")){
            g.drawImage(im2, 0, (im.getHeight()-im2.getHeight())/2, null);

            // CENTRO
            }else if(posicao.equals("5")){
            g.drawImage(im2, (im.getWidth()-im2.getWidth())/2, (im.getHeight()-im2.getHeight())/2, null);
            
            // CENTRO DIREITO
            }else if(posicao.equals("6")){
            g.drawImage(im2, (im.getWidth()-im2.getWidth()), (im.getHeight()-im2.getHeight())/2, null);
            
            // BASE ESQUERDA
            }else if(posicao.equals("1")){
            g.drawImage(im2, 0, (im.getHeight()-im2.getHeight()), null);

            // BASE CENTRO
            }else if(posicao.equals("2")){
            g.drawImage(im2, (im.getWidth()-im2.getWidth())/2, (im.getHeight()-im2.getHeight()), null);
            
            // BASE DIREITA
            }else if(posicao.equals("3")){
            g.drawImage(im2, (im.getWidth()-im2.getWidth()), (im.getHeight()-im2.getHeight()), null);
            }
            
            g.dispose();
            ImageIO.write(im, "jpeg", imagemGerada);
            
            /* ALTERAÇÕES EM  26/12/2008 */
            im.flush();
            im2.flush();
            /* --------------------------- */
            
            imagemOriginal.close();
            imagemWatermark.close();
            imagemGerada.flush();
            imagemGerada.close();
            
            

            } catch (Exception e) {
            System.out.println(e);
            }
}

public static void gerarWatermark(InputStream imagemOriginal, String textoWatermark, OutputStream imagemGerada){

try {

BufferedImage im = ImageIO.read(imagemOriginal);

//Preparando o Graphics 2D para incluir o texto na imagem
Graphics2D g = im.createGraphics();
g.setRenderingHint(RenderingHints.KEY_TEXT_ANTIALIASING, RenderingHints.VALUE_TEXT_ANTIALIAS_ON);
g.setRenderingHint(RenderingHints.KEY_FRACTIONALMETRICS, RenderingHints.VALUE_FRACTIONALMETRICS_ON);
g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);

//Setar a font utilizada no texto
g.setFont(new Font("Lucida Bright", Font.ITALIC, 60));

//Efeitos de rotacao no texto
g.rotate(-Math.PI/4, im.getWidth()/2, im.getHeight()/2);

//Setando o valor do texto
TextLayout tl = new TextLayout(textoWatermark, g.getFont(), g.getFontRenderContext());

//???
Rectangle2D bounds = tl.getBounds();
double x = (im.getWidth()-bounds.getWidth())/2 - bounds.getX();
double y = (im.getHeight()-bounds.getHeight())/2 - bounds.getY();

//
Shape outline = tl.getOutline(AffineTransform.getTranslateInstance(x+2, y+1));

// Montando a saida
g.setComposite(AlphaComposite.getInstance(AlphaComposite.SRC_OVER, 1.0f)); // Estava 0.3
g.setPaint(Color.WHITE);
g.draw(outline);
g.setPaint(new GradientPaint(0, 0, Color.WHITE, 30, 20, new Color(128,128,255), true));
tl.draw(g, (float)x, (float)y);
g.dispose();

ImageIO.write(im, "jpeg", imagemGerada); 
            imagemOriginal.close();
            imagemGerada.close();
            imagemGerada.flush();
            imagemGerada.close();
            


} catch (Exception e) {
System.out.println(e);
}
}

26 Respostas

laelsonc

Aê galera, me acuda ai.

laelsonc

Ninguem conhece ?..to começando a ficar preocupado…

adriano_si

Sabe o que é cara… não é maldade não… é que seu código está macarrão… aí fica difícil achar alguma coisa…

OO aí graças a API do Java… senão…

laelsonc

Cara, não sou expert em JAva, longe disso…mas todas as linhas deste codigo eu entendi a teoria. Além de que estar comentado.
Obs.: Peguei num site gringo especializado.
Tem certeza que vc chegou a lê-lo ? …rsrs

E pelo que entendi a “dificuldade” ai não esta na macarronada, e sim na metodologia usada. Creio que existe bibliotecas mais úteis e eficazes
para fazer isso. Apesar de já ter pesquisado e visto muita coisa, quase tudo a mesma coisa. Por isso estou perguntando para alguém ( que existe com certeza ) que já precisou destes métodos para trabalhos semelhantes.

adriano_si

eu entendi… hehehehehehe… não esquenta véio… todo mundo começa assim. Não lí pq não poderei ajudá-lo tendo em vista que não manjo nada de trabalho de imagens… sacou ?? O que quis dizer foi o seguinte:

Você perguntou isso e eu respondi que não é bem isso… realmente é complicado… se tira alguns minutinhos entre uma tarefa e outra pra tentar ajudar… ler tudo aquilo de código, demanda um tempo, que a maioria que pode lhe ajudar, que complica… entendeu ??

Mas é isso aí… uma hora seu salvador aparece por aqui… ou então tenta sintetizar nos pontos críticos… pode ajudar tbm…

Falows :wink:

adriano_si

Pra não sair do seco da conversa… dá uma olhada aí… não sei se te ajuda…

http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html

adriano_si

Dá uma Googlada também:

http://www.google.com.br/search?q=Thumbnail+em+Java&ie=utf-8&oe=utf-8&aq=t&rls=com.ubuntu:pt-BR:unofficial&client=firefox-a

Marky.Vasconcelos

Postei a um tempo em outro tópico.

Se voce adaptar da pra voce usar no seu código.

int wDest = 250;//largura
int hDest = 250;//altura
BufferedImage src = //Sua imagem
BufferedImage dest = new BufferedImage(wDest,hDest,BufferedImage.TYPE_INT_RGB);//250x250 o tamanho da imagem que vai ficar ao final.
Graphics2D g = dest.createGraphics();
AffineTransform at = AffineTransform.getScaleInstance(
(double)wDest/src.getWidth(),
(double)hDest/src.getHeight());
g.drawRenderedImage(src,at);
//dest agora tem 250x250 pixels e com a imagem redimensionada.
laelsonc

A qualidade fica boa ai do thumb deste código ?

Marky.Vasconcelos

Sim.

laelsonc

Nda. Nenhum dessas funções deixa com a qualidade legal. Como falei com o amigo ai de cima, o problema é no controle do sharp, da nitidez.
Com o java parece q ele dah uma dose exagerada de nitidez, deixando a imagem ruim.
Veja o exemplo do que estou falando:

REDIMENSIONADO DE 3072X2304 para 400X300px

TESTE COM PHOTOSHOP

TESTE COM OS MÉTODOS JAVA ( acima )

Quem souber o que controla a nitidez ai resolve um dos problemas.

furutani

Tenta rodar esse código
http://www.furutani.com.br/site/MostrarArtigo.action?codigo=9
as vezes ajuda

laelsonc

Peguei este método ai:

public static void redimensionar(Image image, int width, int height, int quality,
			String nomeImagem) {

		// Calculos necess�rios para manter as propo�oes da imagem, conhecido
		// como "aspect ratio"
		double thumbRatio = (double) width / (double) height;
		int imageWidth = image.getWidth(null);
		int imageHeight = image.getHeight(null);

		double imageRatio = (double) imageWidth / (double) imageHeight;

		if (thumbRatio < imageRatio) {
			height = (int) (width / imageRatio);
		} else {
			width = (int) (height * imageRatio);
		}
		// Fim do c�lculo

		BufferedImage thumbImage = new BufferedImage(width, height,
				BufferedImage.TYPE_INT_RGB);

		Graphics2D graphics2D = thumbImage.createGraphics();

		graphics2D.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
				RenderingHints.VALUE_INTERPOLATION_BILINEAR);

		graphics2D.drawImage(image, 0, 0, width, height, null);

		BufferedOutputStream out;

		try {

                    String imagesDir = "D:/";

			out = new BufferedOutputStream(new FileOutputStream(imagesDir
					+ nomeImagem));
			JPEGImageEncoder encoder = JPEGCodec.createJPEGEncoder(out);
			JPEGEncodeParam param = encoder
					.getDefaultJPEGEncodeParam(thumbImage);
			quality = Math.max(0, Math.min(quality, 100));
			param.setQuality((float) quality / 100.0f, false);
			encoder.setJPEGEncodeParam(param);
			encoder.encode(thumbImage);
			out.close();

		} catch (FileNotFoundException e) {
			System.out.println("FileNotFoundException " + e.getMessage());
		} catch (ImageFormatException e) {
			System.out.println("ImageFormatException " + e.getMessage());
		} catch (IOException e) {
			System.out.println("IOException " + e.getMessage());
		}
	}

}

e chamei

File file = new File("D:/original.jpg");
		Image imagem = new ImageIcon(file.toURL()).getImage();



                MyImages.redimensionar(imagem, 400, 300, 95, "testeF.jpg");

Mas não funcionou. A Imagem criada ficou preta, sem nada.
Tentei também com:

BufferedImage imagem = ImageIO.read(new File("D:/original.jpg"));
Marky.Vasconcelos

Pra voces.

public static BufferedImage resize(BufferedImage img, int targetWidth,
			int targetHeight) {
		int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB
				: BufferedImage.TYPE_INT_ARGB;
		BufferedImage ret = (BufferedImage) img;
		int w, h;
		w = img.getWidth();
		h = img.getHeight();

		do {
			if (w > targetWidth) {
				w /= 2;
				if (w < targetWidth) {
					w = targetWidth;
				}
			}
			if (h > targetHeight) {
				h /= 2;
				if (h < targetHeight) {
					h = targetHeight;
				}
			}

			BufferedImage tmp = new BufferedImage(w, h, type);
			Graphics2D g2 = tmp.createGraphics();
			g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
					RenderingHints.VALUE_INTERPOLATION_BICUBIC);
			g2.drawImage(ret, 0, 0, w, h, null);
			g2.dispose();

			ret = tmp;
		} while (w != targetWidth || h != targetHeight);

		return ret;
	}

O problema é que é mais demorado… levou 8,5 segundos pra diminuir uma imagem de 2384x3000 para 400x500. Mas a qualidade ficou excelente.

laelsonc
to chamando o método

BufferedImage imagem = ImageIO.read(new File(D:/original.jpg));

MyClass.resize(imagem, 400, 300);

Mas nada acontece… o q tah faltando ?

O método esta completo ?

Marky.Vasconcelos

Faltou atribuir a algum objeto

BufferedImage imagem = ImageIO.read(new File("D:/original.jpg"));
BufferedImage imagemRedimensionada = MyClass.resize(imagem, 400, 300);
laelsonc

Ainda não estamos lá…veja e comparem a qualidade:

PHOTOSHOP

MEUS MÉTODOS ATUAIS JAVA

O METODO DO AMIGO AÍ

SCORE: 2 x 0 pro Photoshop.

AÊ galera, vamo matar essa !!!

T

Laelson, que tal tentar experimentar o ImageMagick?

Embora seja em C, você pode invocá-lo por uma linha de comando (ou seja, via JImageMagick: http://www.imagemagick.org/script/api.php#java )
Talvez haja algum conjunto de parâmetros que crie uma imagem tão boa quanto a do Photoshop. Basta você experimentar um pouco com os parâmetros. É bem capaz de além disso acabar sendo mais rápido que o Java, já que pode usar todos os núcleos do processador caso desejado.

http://www.imagemagick.org/Usage/resize/
http://www.imagemagick.org/Usage/misc/#interpolate

laelsonc

Não entendo nada de C. Tipo, tenho meu sistema/sites hospedados num servidor com Tomcat e etc… Seria possível eu rodar o C no servidor ou vou ter que pedir pra instalar C, módulos e tals e tals… ?

Marky.Vasconcelos

Pelo menos meu método ta um pouco melhor… xD

laelsonc

ATUALIZADO -

O thingol tinha razão. Instalei o Image Magick e é simplesmente covardia. Na chamada padrão ela já converte numa imagem redimensionada perfeita !
Além de ser super rápido. E posso chamar nos meus servlets. Testei umas 10 classes Java que encontrei na net e nada chegou nem perto do ImageMagick. A unica mais ou menos levava uns 4 a 5 segundos para converter, isso com meus 2gb de memória etc. Ponto fraquíssimo do JAVA.

Agora a briga é convencer o meu Servidor a instalá-lo. Pois entrei em contato e me passaram que não tinha ainda por motivo de segurança. Safe_Mode…

Alguém tem alguma experiência usando o Image Magick que queira compartilhar ?
Agradeço.

Valeu !!!

laelsonc

Up

Linkel

Estou à dois dias pesquisando como redimensionar a imagem sem perder tanto a qualidade, assim como vocês aqui…
Em uma das minhas pesquisas achei esse post e tentei usar também as propostas de solução postadas aqui… Mas sem sucesso. A qualidade continuava sempre ruim demais e quando chegava perto de melhorar demorava um abisurdo, rs…
Até que numa das minhas “clicadas” em links alheios cheguei à esse artigo: http://today.java.net/pub/a/today/2007/04/03/perils-of-image-getscaledinstance.html
Com meu inglês fraquinho fui tentando interpretar as dicas meio a tantas maneiras de se redimensionar uma imagem usando apenas java. E entendi que se você redimensionar a imagem original para uma outra imagem vazia usando ScaledImage antes de atribuí-la ao seu objeto Graphics2D a qualidade seria bem melhor e o tempo de processamento menor. Botei, então, a cuca pra funcionar e modifiquei apenas duas linhas daquelas que estava fazendo… E não deu outra! Funcionou como uma luva, rs… Ainda um pouco pesado, mas consegui implementar um método que lê uma imagem num diretório local, copia essa imagem para uma pasta do servidor (que é localhost mesmo, rs), armazena ela em memória, através de BufferedImage, redimensiona a imagem de 2848 X 2136 para 300 X 225 pixels, converte qualquer tipo para jpg e grava novamente a imagem redimensionada no diretório do servidor, excluindo a original, em 3 segundos… E olha que só tenho 1 gb de RAM, meu processador só tem um núcleo e estou rodando meu ubuntu por um live usb, instalado no meu pendrive…
Agora, deixando de ladainha, rsrs, aí estão as míseras linhas de código que redimensionam a imagem:

BufferedImage imageBuffer = new BufferedImage(largura, altura, BufferedImage.TYPE_INT_RGB); Graphics2D graphics2D = imageBuffer.createGraphics(); // aqui é o segredo... redimensiona antes de setar o graphics, com o algoritmo de cálculo de média da área em pixels da imagem... Image scaledImage = imagem.getScaledInstance(largura, altura, Image.SCALE_AREA_AVERAGING); graphics2D.drawImage(scaledImage, 0, 0, largura, altura, null); graphics2D.dispose();Prontinho!
Simples, não!?
Pode não ser tão rápido quanto usando ImageMagik, mas é 100% java e não precisa de “gambiarra” nenhuma pra fazer funcionar, rsrsrsrs…
Com certeza você vai querer modificar pra adequar ainda mais às suas necessidades, e melhorando a ideia poste aqui pra gente poder usurfruir também, rs…
Grande abraço!

rcunhasp

Funcionou sim aqui tambem. Fiz uns ajustes pra escolher a imagem por caixa de escolha (FileChooser)

btn_Wallpaper.addActionListener(new ActionListener() {

public void actionPerformed(ActionEvent arg0) {

	JFileChooser chooser = new JFileChooser();

	if (returnVal == JFileChooser.APPROVE_OPTION) {


		mainGUI.app.Change_Back = chooser.getSelectedFile().getAbsolutePath();
		
		
		BufferedImage fundo = null;
		
		try {
			fundo = ImageIO.read(new File(mainGUI.app.Change_Back));
		} catch (IOException e1) {
			// TODO Auto-generated catch block
			e1.printStackTrace();
			
			JOptionPane.showConfirmDialog(null, "Image fail !");
		}
		
		BufferedImage img_stretched = BufferedImage(fundo, 200, 200);

		ImageIcon icon = new ImageIcon(img_stretched);

                    // Seta a imagem no Jframe mainGUI
		mainGUI.app.lbl_fundo_imagem.setIcon(icon);
}

}

);

R

Marky.Vasconcelos:
Pra voces.

public static BufferedImage resize(BufferedImage img, int targetWidth,
			int targetHeight) {
		int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB
				: BufferedImage.TYPE_INT_ARGB;
		BufferedImage ret = (BufferedImage) img;
		int w, h;
		w = img.getWidth();
		h = img.getHeight();

		do {
			if (w > targetWidth) {
				w /= 2;
				if (w < targetWidth) {
					w = targetWidth;
				}
			}
			if (h > targetHeight) {
				h /= 2;
				if (h < targetHeight) {
					h = targetHeight;
				}
			}

			BufferedImage tmp = new BufferedImage(w, h, type);
			Graphics2D g2 = tmp.createGraphics();
			g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
					RenderingHints.VALUE_INTERPOLATION_BICUBIC);
			g2.drawImage(ret, 0, 0, w, h, null);
			g2.dispose();

			ret = tmp;
		} while (w != targetWidth || h != targetHeight);

		return ret;
	}

O problema é que é mais demorado… levou 8,5 segundos pra diminuir uma imagem de 2384x3000 para 400x500. Mas a qualidade ficou excelente.

Este código não calcula o aspectRation, mas foi o melhor código para redimensionamento que encontrei, fiz uma alteração para calcular o aspectRation, segue

public static byte[] redimensionarImagem(InputStream imagem, int maxWidth,
			int maxHeigth) throws Exception {

		BufferedImage img = ImageIO.read(imagem);

		int imageWidth = img.getWidth();
		int imageHeight = img.getHeight();

		Dimension largestDimension = new Dimension(maxWidth, maxHeigth);

		float aspectRation = (float) imageWidth / imageHeight;

		if (imageWidth > maxWidth || imageHeight > maxHeigth) {

			if ((float) largestDimension.width / largestDimension.height > aspectRation) {
				largestDimension.width = (int) Math
						.ceil(largestDimension.height * aspectRation);
			} else {
				largestDimension.height = (int) Math
						.ceil((float) largestDimension.width / aspectRation);
			}

			maxWidth = largestDimension.width;
			maxHeigth = largestDimension.height;
		}

		return redimensionar(img, maxWidth, maxHeigth);
	}

	private static byte[] redimensionar(BufferedImage img, int targetWidth,
			int targetHeight) throws Exception {

		int type = (img.getTransparency() == Transparency.OPAQUE) ? BufferedImage.TYPE_INT_RGB
				: BufferedImage.TYPE_INT_ARGB;

		BufferedImage ret = (BufferedImage) img;
		int w, h;
		w = img.getWidth();
		h = img.getHeight();

		do {
			if (w > targetWidth) {
				w /= 2;
				if (w < targetWidth) {
					w = targetWidth;
				}
			}
			if (h > targetHeight) {
				h /= 2;
				if (h < targetHeight) {
					h = targetHeight;
				}
			}

			BufferedImage tmp = new BufferedImage(w, h, type);
			Graphics2D g2 = tmp.createGraphics();
			g2.setRenderingHint(RenderingHints.KEY_INTERPOLATION,
					RenderingHints.VALUE_INTERPOLATION_BICUBIC);
			g2.drawImage(ret, 0, 0, w, h, null);
			g2.dispose();

			ret = tmp;
		} while (w != targetWidth || h != targetHeight);

		return bufferedImageToByteArray(ret);
	}
ViniGodoy

Aproveitando o tópico ressuscitado, essa API faz o escalonamento. É de altíssima qualidade, fácil de usar e extremamente rápida:
http://code.google.com/p/java-image-scaling/

Raiduster, ao ressuscitar tópicos, deixe claro que você está ressuscitando e porque. Não responda casualmente a um usuário que postou em 2009, como se ele tivesse feito isso ontem.

Finalmente, o termo correto é aspect ratio, não aspect ratio[color=red]n[/color].

Criado 14 de abril de 2009
Ultima resposta 26 de fev. de 2012
Respostas 26
Participantes 9