2012-03-17 13 views
5

Estoy intentando rotar un archivo JPG en 90 grados. Sin embargo, mi código muestra imagen (BufferedImage) que es completamente negra.Giro de imagen de Java con AffineTransform genera una imagen en negro, pero funciona bien cuando se cambia de tamaño

Ésta es la manera de reproducir: (Descargar 3.jpg here)

private static BufferedImage transform(BufferedImage originalImage) { 
    BufferedImage newImage = null; 
    AffineTransform tx = new AffineTransform(); 
    tx.rotate(Math.PI/2, originalImage.getWidth()/2, originalImage.getHeight()/2); 

    AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BICUBIC); 
    newImage = op.filter(originalImage, newImage); 

    return newImage; 
} 

public static void main(String[] args) throws Exception { 
    BufferedImage bi = transform(ImageIO.read(new File(
      "3.jpg"))); 
    ImageIO.write(bi, "jpg", new File("out.jpg")); 

} 

¿Qué pasa aquí?

(si doy esta salida negro BufferedImage a una biblioteca de imágenes cambiar el tamaño, que se cambia de tamaño, así, la imagen original todavía está allí.)

Respuesta

13

Pasando un nuevo BufferedImage en el método de filtro() en lugar de dejar que crear su trabajos propios (no completamente negros).

Además, la transformación no pareció funcionar correctamente, la imagen terminó siendo compensada en el destino. Pude solucionarlo aplicando manualmente las traducciones necesarias, observe estos trabajos en orden inverso, y en la imagen de destino el ancho = la altura anterior, y la altura = el ancho anterior.

AffineTransform tx = new AffineTransform(); 

// last, width = height and height = width :) 
tx.translate(originalImage.getHeight()/2,originalImage.getWidth()/2); 
tx.rotate(Math.PI/2); 
// first - center image at the origin so rotate works OK 
tx.translate(-originalImage.getWidth()/2,-originalImage.getHeight()/2); 

AffineTransformOp op = new AffineTransformOp(tx, AffineTransformOp.TYPE_BILINEAR); 

// new destination image where height = width and width = height. 
BufferedImage newImage =new BufferedImage(originalImage.getHeight(), originalImage.getWidth(), originalImage.getType()); 
op.filter(originalImage, newImage); 

el Javadoc para el filtro() establece que se creará una BufferedImage para usted, todavía estoy seguro de por qué esto no funciona, tiene que haber un problema aquí.

If the destination image is null, a BufferedImage is created with the source ColorModel. 
5

Si usted fuera abierto a la idea de utilizar un lib 3 ª parte (muy pequeño, sólo 2 clases) imgscalr puede hacer esto para usted en una sola línea mientras se trabaja en torno a todos los aspectos críticos de filtro que diferentes tipos de imágenes puede porque.

Usando Scalr.rotate(...) sería algo como esto:

BufferedImage newImage = Scalr.rotate(originalImage, Rotation.CW_90); 

Si esta rotación es parte de una aplicación más amplia que procesa las imágenes, incluso se puede hacer esto de forma asíncrona si necesitaba que (AsyncScalr class).

imgscalr tiene licencia de Apache 2 y todas las fuentes están disponibles; Si prefieres hacerlo tú mismo con tu mano, lee el code for the rotate() method, he documentado todos los errores que pueden surgir al trabajar con filtros en Java2D.

Espero que ayude!

Cuestiones relacionadas