68 votes

suis-je en train de rendre cela trop compliqué (rotation de l'image)?

J'ai un serveur de code qui génère les miniatures lorsqu'une image est téléchargée. Le problème est que lorsque l'image a été prise et l'appareil photo/appareil a été tourné, les vignettes sont en rotation, même si la taille totale des images elles-mêmes sont affichés dans l'orientation correcte dans tous les logiciels de visualisation d'images. C'est seulement avec jpg.

À l'aide de l'Aperçu sur OSX, je peux voir que jpg avons orientation de métadonnées incorporées à l'intérieur. Lorsque j'utilise ImageTools (Graal Plugin) pour générer une vignette, les métadonnées EXIF n'est pas dans la vignette, c'est pourquoi les miniatures apparaissent en rotation.

Via en mode hors connexion conversations, j'ai appris que, même s'il est relativement facile de lire les métadonnées EXIF, il n'est pas facile de l'écrire, c'est pourquoi les données sont perdues lors de la génération d'une vignette jpg.

Il semble donc, j'ai deux options:

  1. Utiliser ImageMagick pour générer les vignettes. L'inconvénient est qu'il nécessite installé plus de logiciels sur nos serveurs.
  2. Lire les EXIF de données de code et de tourner la vignette de manière appropriée.

Quelqu'un sait-il d'autres options?

73voto

Antoine Martin Points 447

Si vous souhaitez faire pivoter vos images, je vous suggère d'utiliser les métadonnées extracteur de bibliothèque http://code.google.com/p/metadata-extractor/. Vous pouvez obtenir les informations de l'image avec le code suivant:

// Inner class containing image information
public static class ImageInformation {
    public final int orientation;
    public final int width;
    public final int height;

    public ImageInformation(int orientation, int width, int height) {
        this.orientation = orientation;
        this.width = width;
        this.height = height;
    }

    public String toString() {
        return String.format("%dx%d,%d", this.width, this.height, this.orientation);
    }
}


public static ImageInformation readImageInformation(File imageFile)  throws IOException, MetadataException, ImageProcessingException {
    Metadata metadata = ImageMetadataReader.readMetadata(imageFile);
    Directory directory = metadata.getDirectory(ExifIFD0Directory.class);
    JpegDirectory jpegDirectory = (JpegDirectory)metadata.getDirectory(JpegDirectory.class);

    int orientation = 1;
    try {
        orientation = directory.getInt(ExifIFD0Directory.TAG_ORIENTATION);
    } catch (MetadataException me) {
        logger.warn("Could not get orientation");
    }
    int width = jpegDirectory.getImageWidth();
    int height = jpegDirectory.getImageHeight();

    return new ImageInformation(orientation, width, height);
}

Ensuite, compte tenu de l'orientation que vous récupérez, vous pouvez faire pivoter et/ou de retourner l'image à la bonne orientation. La transformation Affine pour l'orientation EXIF est donnée par la méthode suivante:

// Look at http://chunter.tistory.com/143 for information
public static AffineTransform getExifTransformation(ImageInformation info) {

    AffineTransform t = new AffineTransform();

    switch (info.orientation) {
    case 1:
        break;
    case 2: // Flip X
        t.scale(-1.0, 1.0);
        t.translate(-info.width, 0);
        break;
    case 3: // PI rotation 
        t.translate(info.width, info.height);
        t.rotate(Math.PI);
        break;
    case 4: // Flip Y
        t.scale(1.0, -1.0);
        t.translate(0, -info.height);
        break;
    case 5: // - PI/2 and Flip X
        t.rotate(-Math.PI / 2);
        t.scale(-1.0, 1.0);
        break;
    case 6: // -PI/2 and -width
        t.translate(info.height, 0);
        t.rotate(Math.PI / 2);
        break;
    case 7: // PI/2 and Flip
        t.scale(-1.0, 1.0);
        t.translate(-info.height, 0);
        t.translate(0, info.width);
        t.rotate(  3 * Math.PI / 2);
        break;
    case 8: // PI / 2
        t.translate(0, info.width);
        t.rotate(  3 * Math.PI / 2);
        break;
    }

    return t;
}

La rotation de l'image est effectuée par la méthode suivante:

public static BufferedImage transformImage(BufferedImage image, AffineTransform transform) throws Exception {

    AffineTransformOp op = new AffineTransformOp(transform, AffineTransformOp.TYPE_BICUBIC);

    BufferedImage destinationImage = op.createCompatibleDestImage(image,  (image.getType() == BufferedImage.TYPE_BYTE_GRAY)? image.getColorModel() : null );
    Graphics2D g = destinationImage.createGraphics();
    g.setBackground(Color.WHITE);
    g.clearRect(0, 0, destinationImage.getWidth(), destinationImage.getHeight());
    destinationImage = op.filter(image, destinationImage);;
    return destinationImage;
}

Dans un environnement de serveur, n'oubliez pas d'exécuter avec -Djava.awt.headless=true

22voto

dnault Points 1248

La bibliothèque Thumbnailator honore les indicateurs d'orientation EXIF. Pour lire une image en taille réelle avec une orientation correcte:

 BufferedImage image = Thumbnails.of(inputStream).scale(1).asBufferedImage();
 

9voto

Per Lindberg Points 77

Cela peut être fait étonnamment facilement en utilisant la partie image de la bibliothèque principale JavaXT :

 // Browsers today can't handle images with Exif Orientation tag
Image image = new Image(uploadedFilename);
// Auto-rotate based on Exif Orientation tag, and remove all Exif tags
image.rotate(); 
image.saveAs(permanentFilename);
 

C'est ça!

J'ai essayé Apache Commons Imaging, mais c'était un gâchis. JavaXT est beaucoup plus élégant.

3voto

Alex Gitelman Points 15062

Exif semble difficile à écrire en raison de contenus propriétaires. Cependant, vous pouvez envisager une autre option

Lire l'original mais écrire uniquement la balise d'orientation sur les miniatures

Apache Sanselan semble avoir une belle collection d'outils pour le faire.

http://commons.apache.org/proper/commons-imaging/

Regardez la classe ExifRewriter, par exemple.

1voto

karmakaze Points 4615

Si vous voulez juste que ça paraisse bien. Vous pouvez simplement ajouter un "rotation" -PI / 2 (-90 degrés), PI / 2 (90 degrés) ou PI (+180 degrés) selon les besoins en fonction de l '"orientation" que vous avez déjà extraite. Le navigateur ou tout autre programme affichera correctement l'image car l'orientation aura été appliquée et les métadonnées supprimées de la vignette.

Prograide.com

Prograide est une communauté de développeurs qui cherche à élargir la connaissance de la programmation au-delà de l'anglais.
Pour cela nous avons les plus grands doutes résolus en français et vous pouvez aussi poser vos propres questions ou résoudre celles des autres.

Powered by:

X