'Write/Edit metadata in a JPG/PNG image

Usually to read metadata from an image I used PyExifTool witch is very powerfull:

import exiftool 
exiftool.executable = "exiftool.exe" 
img_path = 'test.JPG' 
with exiftool.ExifTool() as et:
    metadata = et.get_metadata(img_path)                # read metadata

To edit an image (resize, crop, etc.) I use a pillow or OpenCV library. Example:

from PIL import Image
img_path = 'test.JPG'
img = Image.open(img_path)
img = img.resize((100,100),Image.BILINEAR) # edit the image
exif = img.info['exif']
img.save('output.jpg',exif=exif)

However, not all the metadata is on the EXIF TAG. For Example:

'Composite:Aperture': 5.6,
'Composite:CircleOfConfusion': 0.0110169622305844,
'Composite:FOV': 73.7398575770811,
'Composite:FocalLength35efl': 24,
'Composite:GPSAltitude': 455.764,
'Composite:GPSLatitude': 41.3867478333333,
'Composite:GPSLongitude': -70.5641583055556,
'Composite:GPSPosition': '41.3867478333333 -70.5641583055556',
'Composite:HyperfocalDistance': 1.25520730117252,
'Composite:ImageSize': '5472 3648',
'Composite:LightValue': 13.2927817492278,
'Composite:Megapixels': 19.961856,
'Composite:ScaleFactor35efl': 2.72727272727273,
'Composite:ShutterSpeed': 0.003125,
'EXIF:ApertureValue': 5.59834346238078,
'EXIF:ColorSpace': 1,
'EXIF:ComponentsConfiguration': '0 3 2 1',
'EXIF:CompressedBitsPerPixel': 3.368460728,
'EXIF:Compression': 6,
'EXIF:Contrast': 0,
'EXIF:CreateDate': '2020:04:11 09:42:31',
'EXIF:CustomRendered': 0,
'EXIF:DateTimeOriginal': '2020:04:11 09:42:31',
'EXIF:DigitalZoomRatio': 'undef',
'EXIF:ExifImageHeight': 3648,
'EXIF:ExifImageWidth': 5472,
'EXIF:ExifVersion': '0230',
'EXIF:ExposureCompensation': -0.34375,
'EXIF:ExposureIndex': 'undef',
'EXIF:ExposureMode': 0,
'EXIF:ExposureProgram': 2,
'EXIF:ExposureTime': 0.003125,
'EXIF:FNumber': 5.6,
'EXIF:FileSource': 3,
'EXIF:Flash': 32,
'EXIF:FlashpixVersion': '0010',
'EXIF:FocalLength': 8.8,
'EXIF:FocalLengthIn35mmFormat': 24,
'EXIF:GPSAltitude': 455.764,
'EXIF:GPSAltitudeRef': 0,
'EXIF:GPSLatitude': 41.3867478333333,
'EXIF:GPSLatitudeRef': 'N',
'EXIF:GPSLongitude': 70.5641583055556,
'EXIF:GPSLongitudeRef': 'W',
'EXIF:GPSVersionID': '2 3 0 0',
'EXIF:GainControl': 0,
'EXIF:ISO': 100,
'EXIF:ImageDescription': 'DCIM\\PANORAMA\\101_0586\\PAN',
'EXIF:InteropIndex': 'R98',
'EXIF:InteropVersion': '0100',
'EXIF:LightSource': 1,
'EXIF:Make': 'DJI',
'EXIF:MaxApertureValue': 2.79917173119039,
'EXIF:MeteringMode': 2,
'EXIF:Model': 'FC6310S',
'EXIF:ModifyDate': '2020:04:11 09:42:31',
'EXIF:Orientation': 1,
'EXIF:ResolutionUnit': 2,
'EXIF:Saturation': 0,
'EXIF:SceneCaptureType': 0,
'EXIF:SceneType': 1,
'EXIF:SerialNumber': '46c76034607b1c0616d67f3643c34a5b',
'EXIF:Sharpness': 0,
'EXIF:ShutterSpeedValue': '0.00312701097912618',
'EXIF:Software': 'v01.08.1719',
'EXIF:SubjectDistance': 0,
'EXIF:SubjectDistanceRange': 0,
'EXIF:ThumbnailImage': '(Binary data 10230 bytes, use -b option to extract)',
'EXIF:ThumbnailLength': 10230,
'EXIF:ThumbnailOffset': 10240,
'EXIF:WhiteBalance': 0,
'EXIF:XPComment': 'Type=N, Mode=P, DE=None',
'EXIF:XPKeywords': 'v01.08.1719;1.3.0;v1.0.0',
'EXIF:XResolution': 72,
'EXIF:YCbCrPositioning': 1,
'EXIF:YResolution': 72,
'ExifTool:ExifToolVersion': 12.05,
'ExifTool:Warning': '[minor] Possibly incorrect maker notes offsets (fix by '
                   '1783?)',
'File:BitsPerSample': 8,
'File:ColorComponents': 3,
'File:Directory': '.',
'File:EncodingProcess': 0,
'File:ExifByteOrder': 'II',
'File:FileAccessDate': '2020:09:12 11:46:45+01:00',
'File:FileCreateDate': '2020:09:12 11:46:45+01:00',
'File:FileModifyDate': '2020:04:21 09:54:42+01:00',
'File:FileName': 'PANO0001.JPG',
'File:FilePermissions': 666,
'File:FileSize': 8689815,
'File:FileType': 'JPEG',
'File:FileTypeExtension': 'JPG',
'File:ImageHeight': 3648,
'File:ImageWidth': 5472,
'File:MIMEType': 'image/jpeg',
'File:YCbCrSubSampling': '2 1',
'MPF:DependentImage1EntryNumber': 0,
'MPF:DependentImage2EntryNumber': 0,
'MPF:ImageUIDList': '(Binary data 66 bytes, use -b option to extract)',
'MPF:MPFVersion': '0010',
'MPF:MPImageFlags': 8,
'MPF:MPImageFormat': 0,
'MPF:MPImageLength': 255918,
'MPF:MPImageStart': 8433897,
'MPF:MPImageType': 65537,
'MPF:NumberOfImages': 2,
'MPF:PreviewImage': '(Binary data 255918 bytes, use -b option to extract)',
'MPF:TotalFrames': 1,
'MakerNotes:CameraPitch': -90,
'MakerNotes:CameraRoll': 0,
'MakerNotes:CameraYaw': -114.099998474121,
'MakerNotes:Make': 'DJI',
'MakerNotes:Pitch': -10.5,
'MakerNotes:Roll': 5.19999980926514,
'MakerNotes:SpeedX': 0,
'MakerNotes:SpeedY': 0,
'MakerNotes:SpeedZ': 0,
'MakerNotes:Yaw': -114.699996948242,
'SourceFile': 'PANO0001.JPG',
'XMP:About': 'DJI Meta Data',
'XMP:AbsoluteAltitude': '+455.76',
'XMP:AlreadyApplied': False,
'XMP:CalibratedFocalLength': 3666.666504,
'XMP:CalibratedOpticalCenterX': 2736.0,
'XMP:CalibratedOpticalCenterY': 1824.0,
'XMP:CamReverse': 0,
'XMP:CreateDate': '2020:04:11',
'XMP:FlightPitchDegree': -10.5,
'XMP:FlightRollDegree': '+5.20',
'XMP:FlightXSpeed': '+0.00',
'XMP:FlightYSpeed': '+0.00',
'XMP:FlightYawDegree': -114.7,
'XMP:FlightZSpeed': '+0.00',
'XMP:Format': 'image/jpg',
'XMP:GPSLatitude': 41.38674784,
'XMP:GPSLongtitude': -70.56415831,
'XMP:GimbalPitchDegree': -90.0,
'XMP:GimbalReverse': 0,
'XMP:GimbalRollDegree': '+0.00',
'XMP:GimbalYawDegree': -114.1,
'XMP:HasCrop': False,
'XMP:HasSettings': False,
'XMP:Make': 'DJI',
'XMP:Model': 'FC6310S',
'XMP:ModifyDate': '2020:04:11',
'XMP:RelativeAltitude': '+69.60',
'XMP:RtkFlag': 0,
'XMP:SelfData': 'Undefined',
'XMP:Version': 7.0

Any suggestion on:

  1. How edit an image and keep the same metadata?
  2. How to edit a specific TAG from the original image?


Solution 1:[1]

Regarding 2) - Just use PIL.Image for that:

TAG_ID = 271

if hasattr(image, '_getexif'):  # only present in JPEGs
    exif = image._getexif()     # returns None if no EXIF data
    if exif is not None:
        try:
            orientation = exif[TAG_ID]
        except KeyError:
            pass
        else:
            exif[TAG_ID] = 'Canon'

Sources

This article follows the attribution requirements of Stack Overflow and is licensed under CC BY-SA 3.0.

Source: Stack Overflow

Solution Source
Solution 1 xxx