saber para metadatos fotos fecha app c# metadata jpeg

para - Cómo agregar ''Comentarios'' a un archivo JPEG usando C#



app para saber fecha de fotos (5)

Dentro de la ventana de propiedades de una imagen JPEG, hay una pestaña llamada "Resumen". Dentro de esta pestaña, hay un campo llamado ''Comentarios''. Me gustaría escribir algún código c # que agregue una cadena dada a este campo, por ejemplo, "Esta es una foto".

¿Alguna clase de alma sabe cómo hacer esto?

Muchas gracias.


Basándome en otras respuestas, escribí la siguiente clase que permite varias manipulaciones de metadatos. Lo usas así:

var jpeg = new JpegMetadataAdapter(pathToJpeg); jpeg.Metadata.Comment = "Some comments"; jpeg.Metadata.Title = "A title"; jpeg.Save(); // Saves the jpeg in-place jpeg.SaveAs(someNewPath); // Saves with a new path

Las diferencias entre mi solución y las otras no son grandes. Principalmente he refactorizado esto para ser más limpio. También utilizo las propiedades de nivel superior de BitmapMetadata , en lugar del método SetQuery .

Aquí está el código completo, que está licenciado bajo la licencia MIT . Deberá agregar referencias a PresentationCore , WindowsBase y System.Xaml .

public class JpegMetadataAdapter { private readonly string path; private BitmapFrame frame; public readonly BitmapMetadata Metadata; public JpegMetadataAdapter(string path) { this.path = path; frame = getBitmapFrame(path); Metadata = (BitmapMetadata)frame.Metadata.Clone(); } public void Save() { SaveAs(path); } public void SaveAs(string path) { JpegBitmapEncoder encoder = new JpegBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(frame, frame.Thumbnail, Metadata, frame.ColorContexts)); using (Stream stream = File.Open(path, FileMode.Create, FileAccess.ReadWrite)) { encoder.Save(stream); } } private BitmapFrame getBitmapFrame(string path) { BitmapDecoder decoder = null; using (Stream stream = File.Open(path, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { decoder = new JpegBitmapDecoder(stream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); } return decoder.Frames[0]; } }


El siguiente código resuelve mi problema y agrega comentarios a una imagen JPEG dada:

public void addImageComment(string imageFlePath, string comments) { string jpegDirectory = Path.GetDirectoryName(imageFlePath); string jpegFileName = Path.GetFileNameWithoutExtension(imageFlePath); BitmapDecoder decoder = null; BitmapFrame bitmapFrame = null; BitmapMetadata metadata = null; FileInfo originalImage = new FileInfo(imageFlePath); if (File.Exists(imageFlePath)) { // load the jpg file with a JpegBitmapDecoder using (Stream jpegStreamIn = File.Open(imageFlePath, FileMode.Open, FileAccess.ReadWrite, FileShare.None)) { decoder = new JpegBitmapDecoder(jpegStreamIn, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); } bitmapFrame = decoder.Frames[0]; metadata = (BitmapMetadata)bitmapFrame.Metadata; if (bitmapFrame != null) { BitmapMetadata metaData = (BitmapMetadata)bitmapFrame.Metadata.Clone(); if (metaData != null) { // modify the metadata metaData.SetQuery("/app1/ifd/exif:{uint=40092}", comments); // get an encoder to create a new jpg file with the new metadata. JpegBitmapEncoder encoder = new JpegBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(bitmapFrame, bitmapFrame.Thumbnail, metaData, bitmapFrame.ColorContexts)); //string jpegNewFileName = Path.Combine(jpegDirectory, "JpegTemp.jpg"); // Delete the original originalImage.Delete(); // Save the new image using (Stream jpegStreamOut = File.Open(imageFlePath, FileMode.CreateNew, FileAccess.ReadWrite)) { encoder.Save(jpegStreamOut); } } } } }

Esta es esencialmente una versión ligeramente modificada del código que se encuentra en el enlace que Konamiman suministró amablemente.

Tenga en cuenta que para hacer este trabajo necesitará agregar referencias de .NET a PresentationCore y WindowsBase . Si usa Visual Studio 2008, esto se puede lograr a través de lo siguiente:

  1. Haga clic derecho en su proyecto en el Explorador de soluciones

  2. En la lista desplegable, seleccione Agregar ''Referencia ...''

  3. Desde el nuevo cuadro que se abre, seleccione la pestaña ''.NET''

  4. Desplácese hasta las dos referencias mencionadas anteriormente y en cada una, haga clic en Aceptar

Muchas gracias a Danbystrom y Konamiman por su ayuda en este asunto. Realmente aprecio la respuesta rápida.


Gracias a las respuestas aquí, he codificado una solución para establecer un comentario usando solo memoria:

public static Image SetImageComment(Image image, string comment) { using (var memStream = new MemoryStream()) { image.Save(memStream, ImageFormat.Jpeg); memStream.Position = 0; var decoder = new JpegBitmapDecoder(memStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); BitmapMetadata metadata; if (decoder.Metadata == null) { metadata = new BitmapMetadata("jpg"); } else { metadata = decoder.Metadata; } metadata.Comment = comment; var bitmapFrame = decoder.Frames[0]; BitmapEncoder encoder = new JpegBitmapEncoder(); encoder.Frames.Add(BitmapFrame.Create(bitmapFrame, bitmapFrame.Thumbnail, metadata, bitmapFrame.ColorContexts)); var imageStream = new MemoryStream(); encoder.Save(imageStream); imageStream.Position = 0; image.Dispose(); image = null; return Image.FromStream(imageStream); } }

No olvide desechar la imagen que se devuelve con este método. (Por ejemplo, después de guardar la imagen en un archivo)


Gracias a los consejos anteriores pude juntar los siguientes. Lo he probado y parece funcionar. Uno de los mayores obstáculos fue determinar la identificación necesaria para el campo que desea asignar.

string fileName = "c:/SomeImage.jpg"; // Retrieve the Image System.Drawing.Image originalImage = System.Drawing.Image.FromFile(fileName); // Get the list of existing PropertyItems. i.e. the metadata PropertyItem[] properties = originalImage.PropertyItems; // Create a bitmap image to assign attributes and do whatever else.. Bitmap bmpImage = new Bitmap((Bitmap)originalImage); // Don''t need this anymore originalImage.Dispose(); // Get / setup a PropertyItem PropertyItem item = properties[0]; // We have to copy an existing one since no constructor exists // This will assign "Joe Doe" to the "Authors" metadata field string sTmp = "Joe DoeX"; // The X will be replaced with a null. String must be null terminated. var itemData = System.Text.Encoding.UTF8.GetBytes(sTmp); itemData[itemData.Length - 1] = 0;// Strings must be null terminated or they will run together item.Type = 2; //String (ASCII) item.Id = 315; // Author(s), 315 is mapped to the "Authors" field item.Len = itemData.Length; // Number of items in the byte array item.Value = itemData; // The byte array bmpImage.SetPropertyItem(item); // Assign / add to the bitmap // This will assign "MyApplication" to the "Program Name" field sTmp = "MyApplicationX"; itemData = System.Text.Encoding.UTF8.GetBytes(sTmp); itemData[itemData.Length - 1] = 0; // Strings must be null terminated or they will run together item.Type = 2; //String (ASCII) item.Id = 305; // Program Name, 305 is mapped to the "Program Name" field item.Len = itemData.Length; item.Value = itemData; bmpImage.SetPropertyItem(item); // Save the image bmpImage.Save(fileName, System.Drawing.Imaging.ImageFormat.Jpeg); //Clean up bmpImage.Dispose();


La parte fácil:

Añadir este elemento de propiedad:

var data = System.Text.Encoding.UTF8.GetBytes( "Some comments" ); PropertyItem pi; *** create an empty PropertyItem here pi.Type = 2; pi.Id = 37510; pi.Len = data.Length; pi.Value = data;

A la colección de PropertItems de la imagen.

La parte algo más engorrosa: ¿Cómo creas un nuevo PropertyItem, ya que no tiene un constructor público?

El "truco" común es tener una imagen vacía alrededor de la cual puedes robar un PropertyItem. suspiro