Domanda

Ho trovato vari codici e librerie per l'editing Exif .

Ma sono senza perdita di dati solo quando la larghezza e l'altezza dell'immagine sono multiple di 16.

Sto cercando una libreria (o anche un modo per farlo da solo) per modificare solo la parte Exif in un file JPEG (o aggiungere dati Exif se non esiste ancora), lasciando gli altri dati non modificati. Non è possibile?

Finora ho trovato solo la parte Exif (inizia con 0xFFE1) ma non capisco come leggere i dati.

È stato utile?

Soluzione

Ecco le specifiche per il formato di interscambio Exif, se prevedi di codificare la tua libreria per la modifica dei tag.

http://www.exif.org/specifications.html

Ecco una libreria scritta in Perl che soddisfa le tue esigenze da cui potresti essere in grado di imparare:

http://www.sno.phy.queensu.ca/~phil / exiftool /

Ecco una discreta libreria .NET per la valutazione Exif da The Code Project :

http://www.codeproject.com/KB/graphics/exiftagcol.aspx

Altri suggerimenti

Puoi farlo senza alcuna lib esterna:

// Create image.
Image image1 = Image.FromFile("c:\\Photo1.jpg");

// Get a PropertyItem from image1. Because PropertyItem does not
// have public constructor, you first need to get existing PropertyItem
PropertyItem propItem = image1.GetPropertyItem(20624);

// Change the ID of the PropertyItem.
propItem.Id = 20625;

// Set the new PropertyItem for image1.
image1.SetPropertyItem(propItem);

// Save the image.
image1.Save("c:\\Photo1.jpg", ImageFormat.Jpg);

Elenco di tutti i possibili ID PropertyItem (incluso exif) che è possibile trovare qui .

Aggiornamento: concordato, questo metodo ricodificherà l'immagine al momento del salvataggio. Ma ho ricordato un altro metodo, in WinXP SP2 e successivamente sono stati aggiunti nuovi componenti di imaging - WIC, e puoi usarli per scrivere senza perdita di metadato - Procedura: ricodificare un'immagine JPEG con metadati .

exiv2net (un wrapper .NET in cima a exiv2) può essere quello che stai cercando.

Ho scritto un piccolo test in cui comprimo più volte un file per vedere il degrado della qualità e puoi vederlo nella terza quarta compressione, il che è molto male.

Ma per fortuna, se usi sempre lo stesso QualityLevel con JpegBitmapEncoder non c'è degrado.

In questo esempio riscrivo le parole chiave 100x nei metadati e la qualità sembra non cambiare.

private void LosslessJpegTest() {
  var original = "d:\\!test\\TestInTest\\20150205_123011.jpg";
  var copy = original;
  const BitmapCreateOptions createOptions = BitmapCreateOptions.PreservePixelFormat | BitmapCreateOptions.IgnoreColorProfile;

  for (int i = 0; i < 100; i++) {
    using (Stream originalFileStream = File.Open(copy, FileMode.Open, FileAccess.Read)) {
      BitmapDecoder decoder = BitmapDecoder.Create(originalFileStream, createOptions, BitmapCacheOption.None);

      if (decoder.CodecInfo == null || !decoder.CodecInfo.FileExtensions.Contains("jpg") || decoder.Frames[0] == null)
        continue;

      BitmapMetadata metadata = decoder.Frames[0].Metadata == null
        ? new BitmapMetadata("jpg")
        : decoder.Frames[0].Metadata.Clone() as BitmapMetadata;

      if (metadata == null) continue;

      var keywords = metadata.Keywords == null ? new List<string>() : new List<string>(metadata.Keywords);
      keywords.Add(<*>quot;Keyword {i:000}");
      metadata.Keywords = new ReadOnlyCollection<string>(keywords);

      JpegBitmapEncoder encoder = new JpegBitmapEncoder {QualityLevel = 80};
      encoder.Frames.Add(BitmapFrame.Create(decoder.Frames[0], decoder.Frames[0].Thumbnail, metadata,
        decoder.Frames[0].ColorContexts));

      copy = original.Replace(".", <*>quot;_{i:000}.");

      using (Stream newFileStream = File.Open(copy, FileMode.Create, FileAccess.ReadWrite)) {
        encoder.Save(newFileStream);
      }
    }
  }
}
Autorizzato sotto: CC-BY-SA insieme a attribuzione
Non affiliato a StackOverflow
scroll top