2009-04-01 9 views
19

Gibt es eine Java-Bibliothek zum Drehen von JPEG-Dateien in Schritten von 90 Grad, ohne Bildverlust?Verlustfreie JPEG-Drehung (90/180/270 Grad) in Java?

+0

nicht in Java, aber http://jpegclub.org/jpegtran/ sollte das beste Kommandozeilen-Dienstprogramm für verlustfreie JPEG-Rotation sein (Windows/Linux) – Henry

+0

Hallo, wenn Sie unter Lösung verwendet haben, würde ich gerne Ihre Hilfe anfordern, wenn Sie können. Ich habe Schwierigkeiten zu finden, wo java.awt.Rectangle zu importieren ist; Ich habe einige Gläser im Web versucht, aber ich kann sie nicht mit Android Studio verwenden. Können Sie mir mit dem Glas helfen, das Sie importiert haben? Danke –

Antwort

-3

Sie keine externe Bibliothek für diese Art der Sache brauchen, es ist alles in SE gebaut. Am einfachsten ist die Funktion rotate() des Graphics2D-Objekts.

Zum Beispiel:

Image rotatedImage = new BufferedImage(imageToRotate.getHeight(null), imageToRotate.getWidth(null), BufferedImage.TYPE_INT_ARGB); 

    Graphics2D g2d = (Graphics2D) rotatedImage.getGraphics(); 
    g2d.rotate(Math.toRadians(90.0)); 
    g2d.drawImage(imageToRotate, 0, -rotatedImage.getWidth(null), null); 
    g2d.dispose(); 

kein Verlust!

Oder, wenn Sie besonders vorsichtig sein möchten, verwenden Sie einfach BufferedImage.getRGB (x, y), und übertragen Sie Pixel für Pixel auf das neue Bild.

+6

Das wäre nicht verlustfrei, da du entschlüsseln müsstest. Kodieren Sie das Bild, was zu Datenverlust führt. JPEGs können verlustfrei in 90-Grad-Schritten gedreht werden, wenn sie korrekt ausgeführt werden. –

+0

Das ist gut für PNG/GIF Ich denke, aber leider nicht verlustfrei zu JPEG. – Henry

+0

Ich verstehe nicht, warum Sie sagen würden, dass dies nicht verlustfrei ist? Vor allem, wenn Sie diese Operation Pixel für Pixel machen? –

6

Aufbauend auf Henrys Antwort, hier ist ein Beispiel dafür, wie MediaUtil verwenden verlustfreie JPEG Rotation auf der Basis der EXIF-Daten auszuführen:

try { 
    // Read image EXIF data 
    LLJTran llj = new LLJTran(imageFile); 
    llj.read(LLJTran.READ_INFO, true); 
    AbstractImageInfo<?> imageInfo = llj.getImageInfo(); 
    if (!(imageInfo instanceof Exif)) 
     throw new Exception("Image has no EXIF data"); 

    // Determine the orientation 
    Exif exif = (Exif) imageInfo; 
    int orientation = 1; 
    Entry orientationTag = exif.getTagValue(Exif.ORIENTATION, true); 
    if (orientationTag != null) 
     orientation = (Integer) orientationTag.getValue(0); 

    // Determine required transform operation 
    int operation = 0; 
    if (orientation > 0 
      && orientation < Exif.opToCorrectOrientation.length) 
     operation = Exif.opToCorrectOrientation[orientation]; 
    if (operation == 0) 
     throw new Exception("Image orientation is already correct"); 

    OutputStream output = null; 
    try { 
     // Transform image 
     llj.read(LLJTran.READ_ALL, true); 
     llj.transform(operation, LLJTran.OPT_DEFAULTS 
       | LLJTran.OPT_XFORM_ORIENTATION); 

     // Overwrite original file 
     output = new BufferedOutputStream(new FileOutputStream(imageFile)); 
     llj.save(output, LLJTran.OPT_WRITE_ALL); 

    } finally { 
     IOUtils.closeQuietly(output); 
     llj.freeMemory(); 
    } 

} catch (Exception e) { 
    // Unable to rotate image based on EXIF data 
    ... 
} 
+0

Ich habe einen Test mit dem Abrufen des EXIF-Rotationstags mit Sanselan und MediaUtil ausgeführt, aber der obige MediaUtil-Ansatz schlägt für mich bei der llj.getImageInfo() fehl; Schritt (keine EXIF-Metadaten finden), wo der Sanselan-Ansatz die EXIF-Metadaten findet. Es scheint, dass LLJtran das Lesen aller modernen JPEGs nicht unterstützt. – JeroenHoek

+0

Ich bin nicht in der Lage, das gespeicherte Bild in meiner Galerie zu sehen..versucht den exakt gleichen Code .. – therealprashant

+0

Ich habe Schwierigkeiten zu finden, wo java.awt.Rectangle zu importieren; Ich habe einige Gläser im Web versucht, aber ich kann sie nicht mit Android Studio verwenden. Können Sie mir mit dem Glas helfen, das Sie importiert haben? Danke –

6

In Bezug auf die Frage der EXIF-Daten müssen nicht unbedingt richtig gehandhabt werden, da EXIF-Daten zeigt Beispielcode ist irrelevant in vielen Situationen, hier ist nur die Funktion LLJTran lossless JPEG Rotation (mit dank user113215):

final File    SrcJPEG = new File("my-input.jpg"); 
final File    DestJPEG = new File("my-output.jpg"); 
final FileInputStream In  = new FileInputStream(SrcJPEG); 

try { 
    final LLJTran   LLJT = new LLJTran(In); 

    LLJT.read(LLJTran.READ_ALL, true); 
    LLJT.transform(LLJTran.ROT_90); 

    final FileOutputStream Out = new FileOutputStream(DestJPEG); 

    try { 
     LLJT.save(Out, LLJTran.OPT_WRITE_ALL); 
    } finally { 
     Out.close(); 
    } 

} finally { 
    In.close(); 
} 

Wenn Sie die Eingabe und Ausgabe File Objekte machen Refe In derselben Datei können Sie dies immer wieder ausführen und beobachten, dass das Bild nicht beeinträchtigt wird, unabhängig davon, wie viele Iterationen durchlaufen werden.

+0

Ich bin nicht in der Lage, Bild zu speichern und es in der Galerie mit dieser Methode zu sehen ... Bitte helfen Sie – therealprashant