18

How can I remove all EXIF data from a JPEG image?

I found lots of examples on how to read and edit the EXIF data with various libraries, but all I would need is a simple example on how to remove it.

It is just for testing proposes, so even the ugliest and hackished approach would be helpful :)

I already tried searching for the EXIF start/end markers 0xFFE1 & 0xFFE2. The last one does not exist in my case.

Peter Mortensen
  • 30,738
  • 21
  • 105
  • 131
marc.d
  • 3,804
  • 5
  • 31
  • 46

4 Answers4

28

I first wrote about this using WPF libs in my blog, but this sort of failed since Windows backend calls are a bit messed up.

My final solution is also much quicker which basically byte patches the jpeg in order to remove the exif. Fast and simple :)

[EDIT: Blog post has more updated code]

namespace ExifRemover
{
  public class JpegPatcher
  {
    public Stream PatchAwayExif(Stream inStream, Stream outStream)
    {
      byte[] jpegHeader = new byte[2];
      jpegHeader[0] = (byte) inStream.ReadByte();
      jpegHeader[1] = (byte) inStream.ReadByte();
      if (jpegHeader[0] == 0xff && jpegHeader[1] == 0xd8)
      {
        SkipExifSection(inStream);
      }

      outStream.Write(jpegHeader,0,2);

      int readCount;
      byte[] readBuffer = new byte[4096];
      while ((readCount = inStream.Read(readBuffer, 0, readBuffer.Length)) > 0)
        outStream.Write(readBuffer, 0, readCount);

      return outStream;
    }

    private void SkipExifSection(Stream inStream)
    {
      byte[] header = new byte[2];
      header[0] = (byte) inStream.ReadByte();
      header[1] = (byte) inStream.ReadByte();
      if (header[0] == 0xff && header[1] == 0xe1)
      {
        int exifLength = inStream.ReadByte();
        exifLength = exifLength << 8;
        exifLength |= inStream.ReadByte();

        for (int i = 0; i < exifLength - 2; i++)
        {
          inStream.ReadByte();
        }
      }
    }
  }
}
Louis Somers
  • 2,560
  • 3
  • 27
  • 57
Mikael Svenson
  • 39,181
  • 7
  • 73
  • 79
  • 2
    This worked perfectly while saving using Bitmap didn't quite work for me. – dance2die Apr 05 '15 at 23:28
  • Mikael, this is a great Solution, but I am curious about something. In `SkipAppHeaderSection` (from your blog, not the code posted here), you're iterating over the bytes in pairs and always checking if the first is `0xff` and if the second is between `0xe0` and `0xef`. How does this indicate the beginning and end of a JPG header? Most curious as to why the first in the pair would always be `0xe0`. – oscilatingcretin Oct 07 '18 at 23:47
  • Been a looong time, but I think I encountered images which had other headers before the exif one, thus I loop until I found the exif one with the correct signature of 0xff 0xe0 – Mikael Svenson Oct 08 '18 at 05:46
5

I think reading in the file into a Bitmap object and writing out to a file again should do the trick.

I remember feeling frustrated while doing my "image rotation program" that it removed the EXIF data. But in this case, it's exactly what you want!

Dave Van den Eynde
  • 17,020
  • 7
  • 59
  • 90
0

what you should avoid is to decode and re-encode your images because this will hurt the quality. instead you should find a way to modify only the metadata. i haven't tried it but i think InPlaceBitmapMetadataWriter will do the trick.

Nick
  • 2,555
  • 1
  • 20
  • 18
  • You're right that decoding/re-encoding will hurt quality (to some extent). I think it's up to the poster to decide if it's worth the effort based upon what he needs. – Dave Van den Eynde Jun 17 '09 at 09:26
  • i looked into it thx, but it`s way to complicated for my use case. – marc.d Jun 19 '09 at 08:48
-2

It's too easy, use jhead.exe from here: http://www.sentex.net/~mwandel/jhead/

Make a little batch file if you want e.g.: jhead.exe -purejpg *.jpg

It will strip all metadata from all jpegs in the same folder.

EdChum
  • 376,765
  • 198
  • 813
  • 562