Home > Blockchain >  How to keep EXIF of an edited image?
How to keep EXIF of an edited image?

Time:09-22

So my program is fixing some image artefacts, it goes like this:

void FixFile(string path)
{
    var bmp = new WriteableBitmap(new BitmapImage(new Uri(path)));
    bmp.Lock();

    // magick

    bmp.Unlock();

    using (var stream = new FileStream(path.Replace("DSC", "fix_DSC"), FileMode.Create))
    {
        var encoder = new JpegBitmapEncoder();
        encoder.Frames.Add(BitmapFrame.Create(bmp));
        encoder.Save(stream);
    }
}

The problem is that fixed image contains no EXIF data. How do I transfer EXIF data from the original image?

CodePudding user response:

you should be able to copy the bitmap metadata property.

So, instead of in-lining "var bmp =...."

create in an instance of BitmapImage then copy that to your new bmp run your magick ;) when encoding your jpeg, use the metadata property from the original file as a parameter to the encoder then save your new file

void FixFile(string path)
        {
            BitmapDecoder bitmapDecoder = BitmapDecoder.Create(new Uri(path), BitmapCreateOptions.None, BitmapCacheOption.OnLoad);
            // I'm not sure if Clone method is required
            BitmapMetadata bitmapMetadata = bitmapDecoder.Metadata.Clone();

            var bmp = new WriteableBitmap(new BitmapImage(new Uri(path)));
            bmp.Lock();

            // magick

            bmp.Unlock();

            using (var stream = new FileStream(path.Replace("DSC", "fix_DSC"), FileMode.Create))
            {
                var encoder = new JpegBitmapEncoder();
                encoder.Frames.Add(BitmapFrame.Create(bmp));
                // again, not sure if clone method is required
                encoder.Metadata = bitmapMetadata.Clone();
                encoder.Save(stream);
            }
        }

https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.bitmapmetadata?view=net-5.0

https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.bitmapdecoder.metadata?view=net-5.0

https://docs.microsoft.com/en-us/dotnet/api/system.windows.media.imaging.bitmapencoder.metadata?view=net-5.0

CodePudding user response:

Load the source bitmap as BitmapFrame, not BitmapImage. Then pass the Metadata property of the source to the new BitmapFrame that is added to the Frames collection of the encoder.

public void FixFile(string path)
{
    var source = BitmapFrame.Create(new Uri(path));
    var metadata = (BitmapMetadata)source.Metadata;

    var bmp = new WriteableBitmap(source);
    bmp.Lock();
    // magick
    bmp.Unlock();

    var target = BitmapFrame.Create(bmp, null, metadata, null); // here

    var encoder = new JpegBitmapEncoder();
    encoder.Frames.Add(target);

    using (var stream = File.OpenWrite(path.Replace("DSC", "fix_DSC")))
    {
        encoder.Save(stream);
    }
}
  • Related