2012-03-17 16 views
5

Sto solo provando a ruotare un file JPG di 90 gradi. Tuttavia il mio codice emette un'immagine (BufferedImage) completamente nera.Rotazione immagine Java con AffineTransform restituisce l'immagine nera, ma funziona correttamente se ridimensionata

Ecco il modo per riprodurre: (Scarica 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")); 

} 

Cosa c'è di sbagliato qui?

(se io do questa uscita nero BufferedImage a una libreria Image Resizer, esso viene ridimensionata bene, immagine originale è ancora lì.)

risposta

13

Passando un nuovo BufferedImage nel filtro() metodo, piuttosto che lasciare che creare la sua proprie opere (non completamente nere).

Anche la trasformazione non sembra funzionare correttamente, l'immagine è stata compensata nella destinazione. Sono stato in grado di risolverlo applicando manualmente le traduzioni necessarie, nota che funzionano in ordine inverso e nell'immagine di destinazione la larghezza = la vecchia altezza e l'altezza = la vecchia larghezza.

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); 

Javadoc per il filtro() afferma che si creerà una BufferedImage per te, io sono ancora sicuri perché questo non funziona, ci deve essere un problema qui.

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

Se si dovesse aperti all'idea di utilizzare un lib 3rd party (molto piccola, appena 2 classi) imgscalr può fare questo per voi in una singola linea mentre si lavora attorno a tutti i trucchi di filtro che i diversi tipi di immagine possono causa.

Utilizzando Scalr.rotate(...) sarebbe simile a questa:

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

Se questa rotazione è parte di un'applicazione più ampio che elabora le immagini, si può anche fare questo in modo asincrono se avevi bisogno che (AsyncScalr class).

imgscalr è sotto una licenza Apache 2 e tutta la sorgente è disponibile; se preferisci farlo da solo, leggere lo code for the rotate() method, ho documentato tutti i trucchi che possono emergere quando si lavora con i filtri in Java2D.

Spero che questo aiuti!

Problemi correlati