c# - una - Problema al leer los metadatos JPEG(Orientación)
programa para ver metadatos de una imagen (5)
Aquí hay un fragmento que aborda los 8 valores de orientación.
Primero algunas notas:
La identificación EXIF 0x0112 es para orientación. Esta es una útil referencia de identificación EXIF http://www.sno.phy.queensu.ca/~phil/exiftool/TagNames/EXIF.html
0x0112 es el equivalente hexadecimal de 274 . El tipo de datos de un PropertyItem.Id
es un int
, lo que significa que 274 es lo que es útil aquí.
Además, se suponía que 5029 probablemente era 0x5029 o 20521, lo que se correlaciona con ThumbnailOrientation, aunque probablemente no es lo que se desea aquí.
Imagen de Oriente:
Nota: img
es un System.Drawing.Image
o hereda de él, como 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);
}
Tengo una imagen JPEG que fue tomada en un iphone. En mi PC de escritorio (Windows Photo Viewer, Google Chrome, etc.) la orientación es incorrecta.
Estoy trabajando en una aplicación web ASP.NET MVC 3 donde necesito subir fotos (actualmente usando plupload).
Tengo un código del lado del servidor para procesar imágenes, incluida la lectura de datos EXIF.
Intenté leer el campo PropertyTagOrientation
en los metadatos EXIF (usando GDI - Image.PropertyItems
), pero el campo no está presente.
Por lo tanto, se trata de metadatos iPhone específicos o de otros metadatos.
He usado otra herramienta como Aurigma Photo Uploader, y lee los metadatos correctamente y rota la imagen. ¿Como hace esto?
¿Alguien sabe qué otros metadatos JPEG podrían contener la información requerida para saber que necesita ser rotada, que es utilizada por Aurigma?
Aquí está el código que estoy usando para leer los datos 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.
}
}
¿Algunas ideas?
Combiné las respuestas y los comentarios, y surgió esto:
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;
}
}
}
De esta publicación parece que debes verificar la 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;
}
}
Escribí una pequeña clase de ayuda para resumir todas las respuestas. También actualizará la etiqueta de orientación Exif de acuerdo con las modificaciones que se realicen en la imagen, lo que puede ser útil si visualiza la imagen en una aplicación de visor ex-aware después de rotarla. Esto también debería resolver el problema planteado por @ShalinJirawla arriba.
using System.Drawing;
using System.Drawing.Imaging;
using System.Linq;
public static class ImageHelper
{
/// <summary>
/// Rotate the given image file according to Exif Orientation data
/// </summary>
/// <param name="sourceFilePath">path of source file</param>
/// <param name="targetFilePath">path of target file</param>
/// <param name="targetFormat">target format</param>
/// <param name="updateExifData">set it to TRUE to update image Exif data after rotation (default is TRUE)</param>
/// <returns>The RotateFlipType value corresponding to the applied rotation. If no rotation occurred, RotateFlipType.RotateNoneFlipNone will be returned.</returns>
public static RotateFlipType RotateImageByExifOrientationData(string sourceFilePath, string targetFilePath, ImageFormat targetFormat, bool updateExifData = true)
{
// Rotate the image according to EXIF data
var bmp = new Bitmap(sourceFilePath);
RotateFlipType fType = RotateImageByExifOrientationData(bmp, updateExifData);
if (fType != RotateFlipType.RotateNoneFlipNone)
{
bmp.Save(targetFilePath, targetFormat);
}
return fType;
}
/// <summary>
/// Rotate the given bitmap according to Exif Orientation data
/// </summary>
/// <param name="img">source image</param>
/// <param name="updateExifData">set it to TRUE to update image Exif data after rotation (default is TRUE)</param>
/// <returns>The RotateFlipType value corresponding to the applied rotation. If no rotation occurred, RotateFlipType.RotateNoneFlipNone will be returned.</returns>
public static RotateFlipType RotateImageByExifOrientationData(Image img, bool updateExifData = true)
{
int orientationId = 0x0112;
var fType = RotateFlipType.RotateNoneFlipNone;
if (img.PropertyIdList.Contains(orientationId))
{
var pItem = img.GetPropertyItem(orientationId);
fType = GetRotateFlipTypeByExifOrientationData(pItem.Value[0]);
if (fType != RotateFlipType.RotateNoneFlipNone)
{
img.RotateFlip(fType);
// Remove Exif orientation tag (if requested)
if (updateExifData) img.RemovePropertyItem(orientationId);
}
}
return fType;
}
/// <summary>
/// Return the proper System.Drawing.RotateFlipType according to given orientation EXIF metadata
/// </summary>
/// <param name="orientation">Exif "Orientation"</param>
/// <returns>the corresponding System.Drawing.RotateFlipType enum value</returns>
public static RotateFlipType GetRotateFlipTypeByExifOrientationData(int orientation)
{
switch (orientation)
{
case 1:
default:
return RotateFlipType.RotateNoneFlipNone;
case 2:
return RotateFlipType.RotateNoneFlipX;
case 3:
return RotateFlipType.Rotate180FlipNone;
case 4:
return RotateFlipType.Rotate180FlipX;
case 5:
return RotateFlipType.Rotate90FlipX;
case 6:
return RotateFlipType.Rotate90FlipNone;
case 7:
return RotateFlipType.Rotate270FlipX;
case 8:
return RotateFlipType.Rotate270FlipNone;
}
}
}
Otra información y un caso de estudio rápido también están disponibles aquí:
Cambiar la orientación de la imagen para fotos de iPhone y / o Android en NET C #
Parece que olvidó que los valores de identificación de orientación que buscó están en hexadecimal. Donde usa 112, debería haber usado 0x112.
Este artículo explica cómo la entrega de orientación con Windows ball-up, y este parece bastante relevante para lo que está haciendo.