简体   繁体   中英

How do I read and write XMP metadata in C#?

I have this method for resizing images, and I have managed to input all of the metadata into the new image except for the XMP data. Now, I can only find topics on how manage the XMP part in C++ but I need it in C#. The closest I've gotten is the xmp-sharp project which is based on some old port of Adobe's SDK, but I can't get that working for me. The MetaDataExtractor project gives me the same results - that is, file format/encoding not supported. I've tried this with .jpg, .png and .tif files.

Is there no good way of reading and writing XMP in C#?

Here is my code if it's of any help (omitting all irrelevant parts):

public Task<Stream> Resize(Size size, Stream image)
{
  using (var bitmap = Image.FromStream(image))
  {
    var newSize = new Size(size.Width, size.Height);
    var ms = new MemoryStream();
    using (var bmPhoto = new Bitmap(newSize.Width, newSize.Height, PixelFormat.Format24bppRgb))
    {
      // This saves all metadata except XMP
      foreach (var id in bitmap.PropertyIdList)
        bmPhoto.SetPropertyItem(bitmap.GetPropertyItem(id));

      // Trying to use xmp-sharp for the XMP part
      try
      {
        IXmpMeta xmp = XmpMetaFactory.Parse(image);
      }
      catch (XmpException e)
      {
        // Here, I always get "Unsupported Encoding, XML parsing failure"
      }

      // Trying to use MetadataExtractor for the XMP part
      try
      {
         var xmpDirs = ImageMetadataReader.ReadMetadata(image).Where(d => d.Name == "XMP");
      }
      catch (Exception e)
      {
        // Here, I always get "File format is not supported"
      }

      // more code to modify image and save to stream
    }
    ms.Position = 0;
    return Task.FromResult<Stream>(ms);
  }
}

The reason you get "File format is not supported" is because you already consumed the image from the stream when you called Image.FromStream(image) in the first few lines.

If you don't do that, you should find that you can read out the XMP just fine.

var xmp = ImageMetadataReader.ReadMetadata(stream).OfType<XmpDirectory().FirstOrDefault();

If your stream is seekable, you might be able to seek back to the origin (using the Seek method, or by setting Position to zero.)

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM