Change EXIF data on JPEG without altering picture


I change the exif on a jpeg using piexif to read and write exif data, which seems to work fine. The issue is when I read and write the jpeg, even tho I don’t change the bytes, it saves the picture with different pixels and the picture that was read. I need it to be exactly the same pixels. I understand this is because jpeg is a lossy format, but the only way I’ve found around it is to save it as a png and then export it as a jpeg with Mac Preview, which is not good, because I have hundreds of pictures.

def adjust_img(path):
   img =
   exif_dict = piexif.load(['exif'])
   new_exif = adjust_exif(exif_dict)
   exif_bytes = piexif.dump(new_exif)
   pc = path.split('/')
   stem = '/'.join(pc[:-1])'%s/_%s' % (stem,pc[-1]), "JPEG", exif=exif_bytes, quality=95, optimize=False)

How can I preserve the picture and just alter the exif?

Asked By: syzygy



exif_dict = piexif.load(path)
new_exif = adjust_exif(exif_dict)
exif_bytes = piexif.dump(new_exif)
piexif.insert(exif_bytes, path)
Answered By: hMatoba

Exiftool is generally the way to go. But suppose you really need to edit EXIFs in your own program?

Try pyexiv2 at
It is recently maintained and working well. An example:

import sys
from pyexiv2 import Image as ImgMeta

DTO_KEY = 'Exif.Photo.DateTimeOriginal'
filename = sys.argv[1]

with ImgMeta(filename) as img_meta:

    exif = img_meta.read_exif()
        dto = exif[DTO_KEY]
    except KeyError:

    # Convert dto to DateTime, add TimeDelta, format as string
    # Here we skip all that to show we can simply modify it:
    new_dto_str = dto + 'Z'

    img_meta.modify_exif({DTO_KEY: new_dto_str})

When I use this I typically do the edits on a backup copy, then move it into place if happy with it.

Answered By: Gringo Suave