Java.io imagens [RESOLVIDO]

Bom dia pessoal!

Estou tendo problemas com isto ha algum tempo… observem:

File input = new File("/home/gustavo/Imagens/logo hti.png");//Seleciona o arquivo do disco			
System.out.println(input.exists());

//Aqui eu redimensiono a imagem a partir do file
BufferedImage imageInput = ImageIO.read(input);
Image img1 = imageInput.getScaledInstance(128, 128, Image.SCALE_DEFAULT);

//Aqui eu salvo no banco, porem etou salvando a original ainda pois nao consigo salvar a redimensionada
FileInputStream inputStream = new FileInputStream(input);   //Carrega o arquivo
PreparedStatement pstmt = BD.connection.prepareStatement("INSERT INTO imagens values (0,?)");
pstmt.setBinaryStream(1,inputStream,(int)input.length());  //Esse sim grava o arquivo no banco de dados
pstmt.executeUpdate();	

Como voces vem, eu consigo carregar a imagem e salvar no banco, tambem consigo redimensionar a imagem antes porem nao consigo salvar (no bd) a modificada, so a original.
Nao manjo tanto de orientacao à objetos assim, sempre me perco com java.io

Alguma luz? (sem ser do celular como ja ouvi pessoas falarem -.-)
Obrigado pessoal!

seu codigo esta fazendo exatamente o que vc esta mandando ele fazer, na linha abaixo, vc esta fazendo o load da imagem original e nao da sua imagem com as novas dimensoes …

FileInputStream inputStream = new FileInputStream(input);   //Carrega o arquivo  

e em termos de design, normalmente eu guardo apenas o path da imagem no banco e o arquivo no file system, mas cada loco com suas manias …

[quote=balrog]seu codigo esta fazendo exatamente o que vc esta mandando ele fazer, na linha abaixo, vc esta fazendo o load da imagem original e nao da sua imagem com as novas dimensoes …

FileInputStream inputStream = new FileInputStream(input);   //Carrega o arquivo  

e em termos de design, normalmente eu guardo apenas o path da imagem no banco e o arquivo no file system, mas cada loco com suas manias …[/quote]

Sim, mas é porque eu nao consigo criar outro File com a Image criada.
Essa é a duvida e como disse antes, estou fazendo o load da imagem original porque ainda nao consigo fazer com a modifica.

" mas cada loco com suas manias …"
Cara, nao encorajo esses tipos de comentarios, acho que devemos saber os motivos antes de criticar, ja usei das duas maneiras e cada caso é um caso, neste preciso salva no banco.

O seu problema é que você precisa resimensionar e ainda manter uma BufferedImage, coisa que o getScaledInstance não faz. Nesse caso, faça o redimensionamento assim:

[code]//Aqui eu redimensiono a imagem a partir do file
BufferedImage imageInput = ImageIO.read(input);

BufferedImage scaled = new BufferedImage(128, 128, BufferedImage.TYPE_INT_ARGB);
Graphics2D g2d = scaled.createGraphics();
g2d.drawImage(imageInput, 0, 0, 128, 128, null);
g2d.dispose();
[/code]

E scaled conterá sua imagem redimensionada, conservando o tipo BufferedImage.

Ah sim, vc pode usar o método do ImageIO.write para escrever diretamente num arquivo, ou mesmo no seu stream.

Legal vini, porem nao deu certo, a assinatura nao bateu ao desenhar a imagem no grafico, linha 6.

“The method drawImage(BufferedImage, BufferedImageOp, int, int) in the type Graphics2D is not applicable for the arguments (BufferedImage, int, int, int, int)”

Tentei algumas coisas mas nao deu certo. Vlw

nao foi uma critica, e sim um comentario, uma critica teria sido se tivesse falado que era uma ideia idiota fazer isso, mas apenas disse que cada um faz sua carroca andar do jeito que preferir

import java.awt.RenderingHints;
import java.awt.geom.AffineTransform;
import java.awt.image.AffineTransformOp;
import java.awt.image.BufferedImage;
import java.io.File;

import javax.imageio.ImageIO;

public class ImageResize {

	private int maxW;
	private int maxH;

	public ImageResize(int maxW, int maxH) {
		this.maxW = maxW;
		this.maxH = maxH;
	}

	public BufferedImage resize(BufferedImage src, boolean distort) {
		if (src == null) {
			throw new NullPointerException("Null image.");
		}
		double xScale = (double) maxW / src.getWidth();
		double yScale = (double) maxH / src.getHeight();
		if (!distort) {
			xScale = Math.min(xScale, yScale);
			yScale = xScale;
		}
		AffineTransform transform = AffineTransform.getScaleInstance(xScale,
				yScale);
		AffineTransformOp op = new AffineTransformOp(transform,
				new RenderingHints(RenderingHints.KEY_ANTIALIASING,
						RenderingHints.VALUE_ANTIALIAS_ON));
		return op.filter(src, null);
	}

	public static void main(String[] args) throws Exception {
		BufferedImage src = ImageIO.read(ImageResize.class
				.getResource("/ilusao.jpg"));
		BufferedImage dst = new ImageResize(600, 600).resize(src, false);
		ImageIO.write(dst, "JPG", new File("teste.jpg"));
		dst = new ImageResize(600, 600).resize(src, true);
		ImageIO.write(dst, "JPG", new File("teste2.jpg"));
	}

}

Troque o “ilusao.jpg” por um arquivo válido no seu computador e veja o resultado.

Os parâmetros inteiros são, respectivamente, a maior largura e altura válidas para sua imagem (ela será redimensionada para atender a esses requisitos).

Caso a variável boolean seja true a imagem será distorcida para alcançar exatamente o tamanho especificado. Caso contrário, apenas diminui um dos lados (o maior) até alcançar o valor específico.

Uma vez que a imagem tenha sido redimensionada, basta mandá-la para o seu banco de dados (usando o próprio ImageIO.write).

Tem razão, faltou um parâmetro. Basta passar null. Já corrigi o código ali em cima. Bastava ter olhado o javadoc.

Otimo vini, funcionou legal, o do marcos tambem, o problema que estou tendo é como criar o meu FileInputStream a partir o novo BufferedImage sem ter que gravar em disco, criar um file e fazer a leitura novamente.

Preciso mandar pro banco sem gravar a nova imagem em disco.

Obrigado gente

No caso, não é necessário usar o InputStream:

[code]
//Crie um ByteArrayOutputStream
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

//Jogue a imagem lá dentro
ImageIO.write(scaled, “png”, byteArrayOutputStream);

//Extraia os bytes da imagem, e use o setBytes para joga-los para o banco
pstmt.setBytes(1, byteArrayOutputStream.toByteArray());[/code]

Isso evita a criação desnecessária de um arquivo no disco. Usar o disco é um processo mais lento, sem falar que não pode ser feito entre multiplas threads, caso você não crie multiplos arquivos.

Blz vini, isso resolve meu problema, vou testar tudo o mais rapido possivel, vlw!

[quote=ViniGodoy]No caso, não é necessário usar o InputStream:

[code]
//Crie um ByteArrayOutputStream
ByteArrayOutputStream byteArrayOutputStream = new ByteArrayOutputStream();

//Jogue a imagem lá dentro
ImageIO.write(scaled, “png”, byteArrayOutputStream);

//Extraia os bytes da imagem, e use o setBytes para joga-los para o banco
pstmt.setBytes(1, byteArrayOutputStream.getBytes());[/code]

Isso evita a criação desnecessária de um arquivo no disco. Usar o disco é um processo mais lento, sem falar que não pode ser feito entre multiplas threads, caso você não crie multiplos arquivos.[/quote]

funcionou legal vini, so uma observacao, o ByteArrayOutputStream nao tem o .getBytes() mas tem o .toByteArray()

Vlw a todos que prestaram atencao.

Tem razão. Desculpe, é que faço os códigos de cabeça aqui, pois não trabalho mais com Java e sim com C#.