2013-04-12 12 views
9

Desidero creare un'applicazione Web che consenta agli utenti di caricare la propria immagine sul server. Quando fanno clic su invia, la loro immagine verrà caricata sul server (multipart). Prima di salvare, voglio fare alcune operazioni con l'immagine, così ho deciso di usare ..ImageIO.read() ruota sempre la mia immagine caricata

ImageIO.read (InputStream)

per ottenere BufferedImage oggetto

ecco il codice :

public static BufferedImage getBufferedImageFromMultipartFile(MultipartFile file) 
throws APIException 
{ 
    BufferedImage bi = null; 

    try 
    { 
     bi = ImageIO.read(file.getInputStream()); 
    } 
    catch (IOException e) 
    { 
     throw new APIException(ErrorCode.SERVER_ERROR, e); 
    } 

    return bi; 
} 

il problema è quando provo a caricare una foto che ha più di larghezza, come 3264 x 2448 (altezza x larghezza) l'altezza, il restituisce sempre un'immagine che è stata ruotata (2448 x 3264).

Esiste una soluzione per risolvere questo problema?

Si tratta di un bug o di una specifica API definita?

Thx.

PS. dispiace per il mio inglese: D

+0

Ho trovato una domanda simile ora, http://stackoverflow.com/questions/9453367/is-javax-imageio-imageio-broken-it-imports-some-images-as-rotated?rq=1. Quindi, il mio problema non è un bug di ImageIO, ma è la specifica dell'API che ImageIO non può leggere i dettagli dell'immagine (orientamento EXIF). GRAZIE. –

risposta

0

problema Molto interessante ... si può provare a risolvere il problema con l'introduzione di un controllo sulla larghezza e l'altezza per essere più grande di 2448 e 3264, rispettivamente, e poi basta scambiare la sua larghezza e l'altezza

utilizzare sotto pezzo di codice:

BufferedImage oldImage = ImageIO.read(file.getInputStream()); 

if (oldImage.getWidth() > 2448 || oldImage.getHeight() > 3264) { 

    BufferedImage newImage = new BufferedImage(oldImage.getWidth(), 
       oldImage.getHeight(), oldImage.getType()); 

    Graphics2D graphics = (Graphics2D) newImage.getGraphics(); 

    graphics.drawImage(oldImage, 0, 0, oldImage.getHeight(), 
       oldImage.getWidth(), null); 

    ByteArrayOutputStream bos = new ByteArrayOutputStream(); 

    ImageIO.write(newImage, "JPG", bos); 
} 
+0

thx. per partecipare, ma penso che la mia parola e la mia grammatica ti rendano incomprensibili. Ora, ho migliorato la mia domanda. –

+1

ok ... ora è chiaro ... gud che SO ha la risposta e lo hai trovato anche tu :) –

5

ImageIO.read() non può leggere l'orientamento dell'immagine se fosse stata scattata con dispositivo mobile.

ho usato i metadati-estrattore di leggere i metadati, penso che sia una buona soluzione: github.com/drewnoakes/metadata-extractor/wiki

<dependency> 
    <groupId>com.drewnoakes</groupId> 
    <artifactId>metadata-extractor</artifactId> 
    <version>2.7.2</version> 
</dependency> 

Leggi orientamento archiviato nella directory exif:

ExifIFD0Directory exifIFD0 = metadata.getDirectory(ExifIFD0Directory.class); 
int orientation = exifIFD0.getInt(ExifIFD0Directory.TAG_ORIENTATION); 

switch (orientation) { 
    case 1: // [Exif IFD0] Orientation - Top, left side (Horizontal/normal) 
    return null; 
    case 6: // [Exif IFD0] Orientation - Right side, top (Rotate 90 CW) 
    return Rotation.CW_90; 
    case 3: // [Exif IFD0] Orientation - Bottom, right side (Rotate 180) 
    return Rotation.CW_180; 
    case 8: // [Exif IFD0] Orientation - Left side, bottom (Rotate 270 CW) 
    return Rotation.CW_270; 
} 

(rotazione è un classe dal org.imgscalr.Scalr framework Io uso ti ruotare l'immagine).

+0

Questo è stato estremamente utile. Anche il codice con le costanti Scalr era esattamente ciò di cui avevo bisogno. – Bill