¿Cómo se clona una imagen Buffered?

Tengo un objeto que tiene muchas imágenes almacenadas, quiero crear un nuevo objeto copiando todas las imágenes almacenadas en el nuevo objeto, pero estas nuevas imágenes pueden ser alteradas y no quiero que las imágenes originales del objeto se alteren alterando el nuevas imágenes de objetos.

¿Está claro?

¿Es esto posible y alguien puede sugerir una buena manera de hacerlo, por favor? He pensado en getSubImage pero leí en alguna parte que cualquier cambio en la subimagen se vuelve a seleccionar en la imagen principal.

Solo quiero poder obtener una copia completamente nueva o clonar una Imagen Buffered

¿Algo como esto?

 static BufferedImage deepCopy(BufferedImage bi) { ColorModel cm = bi.getColorModel(); boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); WritableRaster raster = bi.copyData(null); return new BufferedImage(cm, raster, isAlphaPremultiplied, null); } 

Hago esto:

 public static BufferedImage copyImage(BufferedImage source){ BufferedImage b = new BufferedImage(source.getWidth(), source.getHeight(), source.getType()); Graphics g = b.getGraphics(); g.drawImage(source, 0, 0, null); g.dispose(); return b; } 

Funciona bastante bien y es simple de usar.

El procedimiento mencionado anteriormente falla cuando se aplica a imágenes secundarias. Aquí hay una solución más completa:

 public static BufferedImage deepCopy(BufferedImage bi) { ColorModel cm = bi.getColorModel(); boolean isAlphaPremultiplied = cm.isAlphaPremultiplied(); WritableRaster raster = bi.copyData(bi.getRaster().createCompatibleWritableRaster()); return new BufferedImage(cm, raster, isAlphaPremultiplied, null); } 

Class BufferedImage no implementa la interfaz Cloneable. Por lo tanto, el método de clonación no se anula. Aquí hay una alternativa para una técnica de copia profunda: Java Tip 76: una alternativa a la técnica de copia profunda

Otra forma es usar la clase Graphics2D para dibujar la imagen en una nueva imagen en blanco. Esto realmente no clona la imagen, pero da como resultado una copia de la imagen que se está produciendo.

 public static final BufferedImage clone(BufferedImage image) { BufferedImage clone = new BufferedImage(image.getWidth(), image.getHeight(), image.getType()); Graphics2D g2d = clone.createGraphics(); g2d.drawImage(image, 0, 0, null); g2d.dispose(); return clone; } 

Esto fue increíblemente útil para un progtwig que estoy usando para dibujar cosas, y no pude implementar los estados Deshacer / Rehacer debido a que BufferedImages en las stacks era prácticamente lo mismo.

Por cierto, sugiero todo el camino usando un par de stacks para este tipo de operaciones. Cada vez que haces algo, crea inmediatamente una nueva imagen, utiliza el método deepCopy mencionado anteriormente

 image = deepCopy((BufferedImage) stackUndo.peek()); 

modifique la imagen como lo desee, luego, cuando deje de editar (como cuando suelta el botón del mouse)

 stackUndo.push(image); 

y siempre pinta el elemento en la parte superior de la stack izquierda

 g.drawImage(stackUndo.peek(),x,y,null); 

y luego si realizas alguna operación de deshacer / rehacer, sigue algo como esto

 public void undoOrRedo(String op) { if(op.equals("undo") && stackUndo.size()>1){ stackRedo.push(stackUndo.pop()); repaint(); } if(op.equals("redo") && stackRedo.size()>0){ stackUndo.push(stackRedo.pop()); repaint(); } } 

asegúrese de dejar siempre algo en la stack de la izquierda, porque para pintar, ¡siempre usará el elemento en la parte superior (peek)!

Sé que esta pregunta es bastante antigua, pero para los futuros visitantes, esta es la solución que usaría:

 Image oldImage = getImage(); Image newImage = oldImage.getScaledInstance(oldImage.getWidth(null), oldImage.getHeight(null), Image.SCALE_DEFAULT); 

newImage si el cambio de la newImage imagen recién obtenida también afecta la imagen original de alguna manera.
-> Javadoc para getScaledInstance
-> Javadoc para SCALE_DEFAULT (las otras constantes se enumeran justo debajo de esa)

Intereting Posts