web-dev-qa-db-fra.com

Problème de lecture des métadonnées JPEG (orientation)

J'ai une image JPEG qui a été prise sur un iphone. Sur mon ordinateur de bureau (Visionneuse de photos Windows, Google Chrome, etc.), l'orientation est incorrecte.

Je travaille sur une application Web ASP.NET MVC 3 où je dois télécharger des photos (actuellement avec plupload).

J'ai un code côté serveur pour traiter les images, y compris la lecture de données EXIF.

J'ai essayé de lire le champ PropertyTagOrientation dans les métadonnées EXIF ​​(avec GDI - Image.PropertyItems), mais le champ n'est pas présent.

Il s’agit donc de métadonnées spécifiques pour l’iphone ou d’autres métadonnées.

J'ai utilisé un autre outil comme Aurigma Photo Uploader, qui lit correctement les métadonnées et fait pivoter l'image. Comment fait-il cela?

Est-ce que quelqu'un sait quelles autres métadonnées JPEG pourraient contenir les informations nécessaires pour savoir qu'il est nécessaire de les faire pivoter, ce qui est utilisé par Aurigma?

Voici le code que j'utilise pour lire les données EXIF:

var image = Image.FromStream(fileStream);

foreach (var prop in image.PropertyItems)
{
   if (prop.Id == 112 || prop.Id == 5029)
   {
      // do my rotate code - e.g "RotateFlip"
      // Never get's in here - can't find these properties.
   }
}

Des idées?

48
RPM1984

Il semble que vous ayez oublié que les valeurs d’orientation que vous avez recherchées sont au format hexadécimal. Où vous utilisez 112, vous devriez avoir utilisé 0x112. 

Cet article explique comment la gestion de l’orientation de Windows et celle-ci semblent très pertinentes pour ce que vous faites.

17
spender

Voici un extrait traitant des 8 valeurs d’orientation.

Tout d'abord quelques notes:

L'ID EXIF ​​0x0112 est destiné à l'orientation. C’est une référence utile pour les identifiants EXIF ​​ http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html

0x0112 est l'équivalent hexadécimal de 274. Le type de données d'un PropertyItem.Id est une int, ce qui signifie que 274 est ce qui est utile ici.

De plus, 5029 était probablement supposé être 0x5029 ou 20521, ce qui correspond à ThumbnailOrientation, bien que ce ne soit probablement pas ce que vous souhaitez ici.

Orienter l'image:

Remarque: img est un System.Drawing.Image ou en hérite, comme System.Drawing.Bitmap.

if (Array.IndexOf(img.PropertyIdList, 274) > -1)
{
    var orientation = (int)img.GetPropertyItem(274).Value[0];
    switch (orientation)
    {
        case 1:
            // No rotation required.
            break;
        case 2:
            img.RotateFlip(RotateFlipType.RotateNoneFlipX);
            break;
        case 3:
            img.RotateFlip(RotateFlipType.Rotate180FlipNone);
            break;
        case 4:
            img.RotateFlip(RotateFlipType.Rotate180FlipX);
            break;
        case 5:
            img.RotateFlip(RotateFlipType.Rotate90FlipX);
            break;
        case 6:
            img.RotateFlip(RotateFlipType.Rotate90FlipNone);
            break;
        case 7:
            img.RotateFlip(RotateFlipType.Rotate270FlipX);
            break;
        case 8:
            img.RotateFlip(RotateFlipType.Rotate270FlipNone);
            break;
    }
    // This EXIF data is now invalid and should be removed.
    img.RemovePropertyItem(274);
}
110
ReenignE

D'après cet article on dirait que vous devez vérifier l'ID 274

foreach (PropertyItem p in properties) {
      if (p.Id == 274) {
            Orientation = (int)p.Value[0];
         if (Orientation == 6)
            oldImage.RotateFlip(RotateFlipType.Rotate90FlipNone);
         if (Orientation == 8)
            oldImage.RotateFlip(RotateFlipType.Rotate270FlipNone);
      break;
      }
}
15
Bala R

J'ai combiné les réponses et les commentaires donnés et suis venu ceci:

    MemoryStream stream = new MemoryStream(data);
    Image image = Image.FromStream(stream);

    foreach (var prop in image.PropertyItems) {
        if ((prop.Id == 0x0112 || prop.Id == 5029 || prop.Id == 274)) {
            var value = (int)prop.Value[0];
            if (value == 6) {
                image.RotateFlip(RotateFlipType.Rotate90FlipNone);
                break;
            } else if (value == 8) {
                image.RotateFlip(RotateFlipType.Rotate270FlipNone);
                break;
            } else if (value == 3) {
                image.RotateFlip(RotateFlipType.Rotate180FlipNone);
                break;
            } 
        }
    }
12
Ron Burgundy

Publier ici au cas où quelqu'un aurait le même problème. J'ai eu des problèmes en production en lisant l'orientation avec WFP et GDI. La seule chose qui a fonctionné utilisait: https://github.com/dlemstra/Magick.NET

Le code est assez simple:

var img = new MagickImage(inputStream);
img.AutoOrient();   // Fix orientation
img.Strip();        // remove all EXIF information
img.Write(outputPath);
0
Diego Jancic