Reputation: 3844
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.
Upvotes: 19
Views: 21659
Reputation: 61727
Been a long time since this question but ran into an issue with this recently. These two functions will remove EXIF data from JPG's provided either as a filepath or byte[] array, without needing any third party packages.
internal static class ExifRemover
{
internal static byte[] RemoveExifDataFromImage(string filePath)
{
using (var originalImage = Image.FromFile(filePath))
{
return Copy(originalImage);
}
}
internal static byte[] RemoveExifDataFromImage(byte[] imageBytes)
{
using (var ms = new MemoryStream(imageBytes))
using (var originalImage = Image.FromStream(ms))
{
return Copy(originalImage);
}
}
private static byte[] Copy(Image originalImage)
{
using (var newImage = new Bitmap(originalImage.Width, originalImage.Height))
using (var g = Graphics.FromImage(newImage))
{
g.DrawImage(originalImage, 0, 0, originalImage.Width, originalImage.Height);
var b = new Bitmap(newImage);
var converter = new ImageConverter();
return (byte[])converter.ConvertTo(b, typeof(byte[]));
}
}
}
It works by copying the image to a new bitmap. With the returned byte array, you can call context.Response.BinaryWrite
to write the image to the response.
Upvotes: 0
Reputation: 39695
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();
}
}
}
}
}
Upvotes: 28
Reputation: 3
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.
Upvotes: -3
Reputation: 2575
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.
Upvotes: 0
Reputation: 17405
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!
Upvotes: 5