Search code examples
imagemetadataexifexiftool

"Blur" photo metadata from command line?


Reposted from Superuser at another user's suggestion since this is likely to involve some (rudimentary) programming.

When I'm posting photographs to social media, I often want to blur parts of the image to remove personally-identifiable-data. This is straightforward with any number of image manipulation tools. Suppose I want to do something roughly equivalent with the picture metadata? For example, I'd like to randomly skew the date and time taken, so that someone interested can still get a rough idea of when it was taken (date and time of day), and randomly skew the GPS coordinates--say, round them to the nearest quarter-mile. I might or might not want to remove other data such as the camera type. It needn't be precise, just anonymize the metadata enough that I don't feel icky about someone knowing exactly when and where I was. It seems straightforward to do this using EXIFTool but the reading, skewing, and then rewriting of metadata would be a bit cumbersome. Not wanting to reinvent the wheel, is there a straightforward way to do this? Thanks for any help.


Solution

  • You can do this with exiftool, though it takes a little knowledge of the inner workings and of Perl.

    As an example, I'll "blur" the time randomly by a 10 minute span (+/- 5 minutes) (ok, technically it's 9 min 59 sec, there's a chance it lands on 0):
    exiftool -d %s "-DateTimeOriginal<${DateTimeOriginal;$_+=(int(rand(600))-300)}" <FileOrDir>

    Breakdown:
    -d %s - This changes the date format to UNIX time, the number of seconds since 1970:01:01 00:00:00
    -DateTimeOriginal< - The tag that's being copied to, presumably the same as the tag being copied from. The Less Than sign < indicates a tag copy operation.
    ${DateTimeOriginal;$_+=(int(rand(600))-300)} - The tag that's being copied from with some changes using exiftools Advanced Formatting Feature (aka Perl code). Because of the -d option, this DateTimeOriginal tag value is in the UNIX time format. Then, a random number between 0 and 599 is generated int(rand(600)), subtract 300 to split it so a little more than half is negative and the rest positive (or 0). Use the default variable $_ and add that to the number generated +=.

    To blur the GPSLatitude and GPSLongitude, you do something similar, using decimal coordinates instead of degrees/minutes/seconds, and much smaller numbers because even tenths of a degree can be many miles. In this case, the important part of the command would be similar to
    "-GPSLatitude<${GPSLatitude#;$_+=(rand()-.5)/10}"
    Here I used the hashtag # with GPSLatitude as that will give the decimal coordinate value. Another option would have been to use the -c option. I also brought it to the 100th decimal for the level of change, which I think maybe in the miles or tens of miles range. This will break down badly near the equator and the meridian as it doesn't take into account hemisphere properly.

    To put it all together:
    exiftool -d %s "-DateTimeOriginal<${DateTimeOriginal;$_+=(int(rand(600))-300)}" "-GPSLatitude<${GPSLatitude#;$_+=(rand()-.5)/10}" "-GPSLongitude<${GPSLongitude#;$_+=(rand()-.5)/10}" <FileOrDir>

    This command creates backup files. Add -overwrite_original to suppress the creation of backup files. Add -r to recurse into subdirectories. If this command is run under Unix/Mac, reverse any double/single quotes to avoid bash interpretation.