Zoom em Imagens GIGANTES

4 respostas
caarlos0

Bom dia,
gostaria de alguma ajuda.

Tenho uma imagem de 26000x6000 pixels (em jpg), e ao tentar efetuar zoom de várias formas (JAI, Graphics2D etc), ocorrem erros de “java.lang.OutOfMemoryError: Java heap space”, ou, a imagem fica com uma qualidade simplesmente HORRÍVEL.

O zoom em questão é para diminuir a imagem mesmo, estou tentando desenvolver um algoritmo de deep zoom (estilo google maps, várias imagens de 256x256 px), o algoritmo para cortar a imagem está pronto, só não sei como fazer o zoom.

meus métodos estão assim:

private static BufferedImage createCompatibleImage(BufferedImage image)
	{
		System.out.println("Pyramid.createCompatibleImage()");
		GraphicsConfiguration gc = BufferedImageGraphicsConfig.getConfig(image);
		int w = image.getWidth();
		int h = image.getHeight();
		BufferedImage result = gc.createCompatibleImage(w, h, Transparency.TRANSLUCENT);  // aqui já ocorre o erro
		Graphics2D g2 = result.createGraphics();
		g2.drawRenderedImage(image, null);
		g2.dispose();
		return result;
	}

public static BufferedImage blurImage(BufferedImage image)
	{
		System.out.println("Pyramid.blurImage()");
		float ninth = 1.0f / 9.0f;
		float[] blurKernel = {ninth, ninth, ninth, ninth, ninth, ninth, ninth, ninth, ninth};
		
		Map map = new HashMap();
		
		map.put(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		
		map.put(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
		
		map.put(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		
		RenderingHints hints = new RenderingHints(map);
		BufferedImageOp op = new ConvolveOp(new Kernel(3, 3, blurKernel), ConvolveOp.EDGE_NO_OP, hints);
		BufferedImage r = op.filter(image, null);
		return r;
	}

private static BufferedImage resize(BufferedImage image, int width, int height)
	{
		System.out.println("Pyramid.resize()");
		int type = image.getType() == 0 ? BufferedImage.TYPE_INT_ARGB : image.getType();
		BufferedImage resizedImage = new BufferedImage(width, height, type);
		Graphics2D g = resizedImage.createGraphics();
		g.setComposite(AlphaComposite.Src);
		
		g.setRenderingHint(RenderingHints.KEY_INTERPOLATION, RenderingHints.VALUE_INTERPOLATION_BILINEAR);
		
		g.setRenderingHint(RenderingHints.KEY_RENDERING, RenderingHints.VALUE_RENDER_QUALITY);
		
		g.setRenderingHint(RenderingHints.KEY_ANTIALIASING, RenderingHints.VALUE_ANTIALIAS_ON);
		
		g.drawImage(image, 0, 0, width, height, null);
		g.dispose();
		return resizedImage;
	}
	
	private static BufferedImage resizeTrick(BufferedImage image, float scale)
	{
		System.out.println("Pyramid.resizeTrick()");
		float width = image.getWidth() * scale;
		float height = image.getHeight() * scale;
		image = createCompatibleImage(image);
		image = blurImage(image);
		image = resize(image, (int) width, (int) height);
		return image;
	}

public static void main(String[] args) throws IOException
	{
		
		Pyramid t = new Pyramid();
		
		//t.testJAI();
		BufferedImage image = ImageIO.read(new File("world.jpg"));
		//t.corta(image);
		
		ImageIO.write(t.resizeTrick(image, 0.7f), "PNG", new File("666.png"));
		
	}

alguma idéia?
obrigado desde já.

abraço

4 Respostas

ViniGodoy

Se você precisa carregar uma imagem desse tamanho na memória, é melhor aumentar bastante o limite de memória máximo da sua VM. Em quanto está?

caarlos0

já coloquei até 2048M, e não vai mesmo assim =/

caarlos0

mais alguma idéia?

caarlos0

algo diferente de bufferedImage que consuma menos memória?

Criado 23 de abril de 2010
Ultima resposta 28 de abr. de 2010
Respostas 4
Participantes 2