Search code examples
c#image-processingexif

Remove all but two fields in EXIF data of a jpeg image using C#


I am using C# and the ImageFactory library (from ImageProcessor.org) to greatly modify a jpg image. It does straightening, cropping, shadow detail enhancement, etc. .

It is fully working and successfully writes the new image to a file. But this file contains the original EXIF data, most of which is now incorrect or irrelevant.

I definitely need to keep the orientation flag in the EXIF data, as it is needed to correctly orient the modified image. And I want to keep the DateTime. But all the other EXIF data should go away.

I can find ways to add or modify an EXIF propertyitem in the image metadata, but no way to remove one.

     using (ImageFactory ifact = new ImageFactory()) {
        ifact.PreserveExifData = true;
        ifact.Load(edat.ImageFilename);

        // save the image in a bitmap that will be manipulated
        //ifact.PreserveExifData = false;  // tried this but b1 still had EXIF data
        Bitmap b1 = (Bitmap)ifact.Image;

        //lots of processsing here...

        // write the image to the output file
        b1.Save(outfilename, ImageFormat.Jpeg);
      }

Solution

  • I finally figured out how to remove all unwanted EXIF tags.

    Those that remain may also be modified.

      // remove unneeded EXIF data
      using (ImageFactory ifact = new ImageFactory()) {
        ifact.PreserveExifData = true;
        ifact.Load(ImageFilename);
        // IDs to keep: model, orientation, DateTime, DateTimeOriginal
        List<int> PropIDs = new List<int>(new int[] { 272, 274, 306, 36867 });
        // get the property items from the image
        ConcurrentDictionary<int, PropertyItem> EXIF_Dict = ifact.ExifPropertyItems;
        List<int> foundList = new List<int>();
        foreach (KeyValuePair<int, PropertyItem> kvp in EXIF_Dict) foundList.Add(kvp.Key);
        // remove EXIF tags unless they are in the PropIDs list
        foreach (int id in foundList) {
          PropertyItem junk;
          if (!PropIDs.Contains(id)) {
            // the following line removes a tag
            EXIF_Dict.TryRemove(id, out junk);
          }
        }
        // change the retained tag's values here if desired
        EXIF_Dict[274].Value[0] = 1;
        // save the property items back to the image
        ifact.ExifPropertyItems = EXIF_Dict;
      }