Closed mol3earth closed 2 years ago
Please provide a copy of your image so that we can replicate the problem.
Thanks for the reply. Here is a zip file of the .tiff file.
Depending on what data you're after, you may appreciate this.
from PIL import Image
img = Image.open('20191002_151243_137.TIFF')
print(img.tag_v2)
gives
{256: 640, 257: 512, 258: (16,), 259: 1, 262: 1, 271: 'FLIR', 272: 'Duo Pro R', 273: (8,), 339: (1,), 277: 1, 278: 512, 279: (655360,), 282: 1.0, 283: 1.0, 284: 1, 296: 1, 297: (0, 1), 50735: '278290', 305: 'V01.02.05', 700: b'<?xpacket begin="" id="W5M0MpCehiHzreSzNTczkc9d"?>\r\n<rdf:RDF xmlns:rdf="http://www.w3.org/1999/02/22-rdf-syntax-ns#"\r\nxmlns:Camera="http://pix4d.com/camera/1.0/"\r\nxmlns:FLIR="http://ns.flir.com/xmp/1.0/">\r\n<rdf:Description rdf:about="">\r\n<Camera:BandName>\r\n<rdf:Seq>\r\n<rdf:li>LWIR</rdf:li>\r\n</rdf:Seq>\r\n</Camera:BandName>\r\n<Camera:CentralWavelength>\r\n<rdf:Seq>\r\n<rdf:li>10000</rdf:li>\r\n</rdf:Seq>\r\n</Camera:CentralWavelength>\r\n<Camera:WavelengthFWHM>\r\n<rdf:Seq>\r\n<rdf:li>4500</rdf:li>\r\n</rdf:Seq>\r\n</Camera:WavelengthFWHM>\r\n<Camera:TlinearGain>0.04</Camera:TlinearGain>\r\n<Camera:Yaw>-11954/100</Camera:Yaw>\r\n<Camera:Pitch>-8497/100</Camera:Pitch>\r\n<Camera:Roll>9660/100</Camera:Roll>\r\n<Camera:GPSXYAccuracy>1.92</Camera:GPSXYAccuracy>\r\n<Camera:GPSZAccuracy>2.79</Camera:GPSZAccuracy>\r\n<Camera:GyroRate>2.55</Camera:GyroRate>\r\n<Camera:DetectorBitDepth>16</Camera:DetectorBitDepth>\r\n<Camera:IsNormalized>1</Camera:IsNormalized>\r\n<FLIR:ImageOffsetX>0</FLIR:ImageOffsetX>\r\n<FLIR:ImageOffsetY>0</FLIR:ImageOffsetY>\r\n<FLIR:ImageValidStartX>0</FLIR:ImageValidStartX>\r\n<FLIR:ImageValidEndX>639</FLIR:ImageValidEndX>\r\n<FLIR:ImageValidStartY>0</FLIR:ImageValidStartY>\r\n<FLIR:ImageValidEndY>511</FLIR:ImageValidEndY>\r\n<FLIR:ImageUpsampleMode>2</FLIR:ImageUpsampleMode>\r\n<FLIR:MAVVersionID>0.3.0.0</FLIR:MAVVersionID>\r\n<FLIR:MAVComponentID>100</FLIR:MAVComponentID>\r\n<FLIR:MAVRelativeAltitude>0/1000</FLIR:MAVRelativeAltitude>\r\n<FLIR:MAVRateOfClimbRef>M</FLIR:MAVRateOfClimbRef>\r\n<FLIR:MAVRateOfClimb>0/1000</FLIR:MAVRateOfClimb>\r\n<FLIR:MAVYaw>0/100</FLIR:MAVYaw>\r\n<FLIR:MAVPitch>0/100</FLIR:MAVPitch>\r\n<FLIR:MAVRoll>0/100</FLIR:MAVRoll>\r\n<FLIR:MAVYawRate>0/100</FLIR:MAVYawRate>\r\n<FLIR:MAVPitchRate>0/100</FLIR:MAVPitchRate>\r\n<FLIR:MAVRollRate>0/100</FLIR:MAVRollRate>\r\n</rdf:Description>\r\n</rdf:RDF>\r\n<?xpacket end="w"?>\x00'}
thanks for your reply!
yes, I had found that already but i need the exif tags, i.e. GPS information.
on a related note, I can't add exif tags to a .tiff file either. I can do so with a .jpg file.
it seems these issues are related to the .tiff file format.
import piexif
import numpy as np
from PIL import Image
# make a dict of exif tags
exif_bytes = piexif.dump( exif_dict )
# make array of random data
arr = np.random.randint(0, 255, size=[100, 100, 3], dtype=np.uint8)
# use fromarray method to convert to img
img = Image.fromarray(arr)
# add exif bytes to image,
img.info['exif'] = exif_bytes
# this save it
img.save(
'temp.tiff',
format='tiff',
)
# Alternately, pass the exif_bytes to the save method.
img.save(
'temp.tiff',
format='tiff',
exif=exif_bytes
)
Neither assigning the exif_bytes
to info
, nor passing it as an argument to save()
work for me.
Image.open()
does not recognize the exif tags I added.
bump? any ideas here?
When Pillow saves TIFF images, it does not use 'exif' from the info
dictionary. Instead, 'tiffinfo' can be used - https://pillow.readthedocs.io/en/stable/handbook/image-file-formats.html#saving-tiff-images
Looking for the GPS info in your image, Pillow reports that there is a GPS IFD, but that it has type 13. This is unexpected, because page 16 of the specification only lists up to 12. Whatever program has created your image appears to have instead followed TIFF Specification Supplement 1, which specifies type 13 as IFD.
So Pillow doesn't currently support reading the GPS data from your image, and it would need to be added. Would you be able to give permission to add your image to the our test suite, and distribute it under the Pillow license?
Hi! Thanks so much for the response and the info.
You can definitely use the image in your test suite and license it as such.
Do you have a timeline for when the package will be updated to work for our images?
Since you're interested in an immediate solution, does this suit your needs?
from PIL import Image, TiffTags
from PIL.TiffImagePlugin import ImageFileDirectory_v2
# Add IFD as a tag type
ImageFileDirectory_v2._load_dispatch[13] = ImageFileDirectory_v2._load_dispatch[TiffTags.LONG]
im = Image.open('20191002_151243_137.TIFF')
gps_offset = im.tag_v2.get(0x8825)
if gps_offset:
ifh = b"II\x2A\x00\x08\x00\x00\x00" if im.tag_v2._endian == "<" else "MM\x00\x2A\x00\x00\x00\x08"
info = ImageFileDirectory_v2(ifh)
im.fp.seek(gps_offset)
info.load(im.fp)
data = {}
gps_keys = ['GPSVersionID','GPSLatitudeRef','GPSLatitude','GPSLongitudeRef','GPSLongitude','GPSAltitudeRef','GPSAltitude','GPSTimeStamp','GPSSatellites','GPSStatus','GPSMeasureMode','GPSDOP','GPSSpeedRef','GPSSpeed','GPSTrackRef','GPSTrack','GPSImgDirectionRef','GPSImgDirection','GPSMapDatum','GPSDestLatitudeRef','GPSDestLatitude','GPSDestLongitudeRef','GPSDestLongitude','GPSDestBearingRef','GPSDestBearing','GPSDestDistanceRef','GPSDestDistance','GPSProcessingMethod','GPSAreaInformation','GPSDateStamp','GPSDifferential']
for k, v in info.items():
print(gps_keys[k]+": "+str(v))
else:
print("No GPS data present")
Running it over your image, I get
GPSVersionID: b'\x03\x02\x00\x00'
GPSLatitudeRef: N
GPSLatitude: (35.0, 35.0, 59.995)
GPSLongitudeRef: W
GPSLongitude: (111.0, 39.0, 42.578)
GPSAltitudeRef: b'\x00'
GPSAltitude: 1845.656
GPSMapDatum: WGS-84
This is now marginally simpler with Pillow 8.0, thanks to #4979
from PIL import Image, TiffTags
from PIL.TiffImagePlugin import ImageFileDirectory_v2
im = Image.open('20191002_151243_137.TIFF')
gps_offset = im.tag_v2.get(0x8825)
if gps_offset:
ifh = b"II\x2A\x00\x08\x00\x00\x00" if im.tag_v2._endian == "<" else "MM\x00\x2A\x00\x00\x00\x08"
info = ImageFileDirectory_v2(ifh)
im.fp.seek(gps_offset)
info.load(im.fp)
data = {}
gps_keys = ['GPSVersionID','GPSLatitudeRef','GPSLatitude','GPSLongitudeRef','GPSLongitude','GPSAltitudeRef','GPSAltitude','GPSTimeStamp','GPSSatellites','GPSStatus','GPSMeasureMode','GPSDOP','GPSSpeedRef','GPSSpeed','GPSTrackRef','GPSTrack','GPSImgDirectionRef','GPSImgDirection','GPSMapDatum','GPSDestLatitudeRef','GPSDestLatitude','GPSDestLongitudeRef','GPSDestLongitude','GPSDestBearingRef','GPSDestBearing','GPSDestDistanceRef','GPSDestDistance','GPSProcessingMethod','GPSAreaInformation','GPSDateStamp','GPSDifferential']
for k, v in info.items():
print(gps_keys[k]+": "+str(v))
else:
print("No GPS data present")
With #5416, this is now as simple as
from PIL import Image
img = Image.open('20191002_151243_137.TIFF')
info = img.getexif().get_ifd(0x8825)
if info:
gps_keys = ['GPSVersionID','GPSLatitudeRef','GPSLatitude','GPSLongitudeRef','GPSLongitude','GPSAltitudeRef','GPSAltitude','GPSTimeStamp','GPSSatellites','GPSStatus','GPSMeasureMode','GPSDOP','GPSSpeedRef','GPSSpeed','GPSTrackRef','GPSTrack','GPSImgDirectionRef','GPSImgDirection','GPSMapDatum','GPSDestLatitudeRef','GPSDestLatitude','GPSDestLongitudeRef','GPSDestLongitude','GPSDestBearingRef','GPSDestBearing','GPSDestDistanceRef','GPSDestDistance','GPSProcessingMethod','GPSAreaInformation','GPSDateStamp','GPSDifferential']
for k, v in info.items():
print(gps_keys[k]+": "+str(v))
else:
print("No GPS data present")
I've created #5575 to resolve this. With that PR, you should also be able to save a TIFF with the exif
keyword argument.
from PIL import Image
def print_gps_data(exif):
info = exif.get_ifd(0x8825)
if info:
gps_keys = ['GPSVersionID','GPSLatitudeRef','GPSLatitude','GPSLongitudeRef','GPSLongitude','GPSAltitudeRef','GPSAltitude','GPSTimeStamp','GPSSatellites','GPSStatus','GPSMeasureMode','GPSDOP','GPSSpeedRef','GPSSpeed','GPSTrackRef','GPSTrack','GPSImgDirectionRef','GPSImgDirection','GPSMapDatum','GPSDestLatitudeRef','GPSDestLatitude','GPSDestLongitudeRef','GPSDestLongitude','GPSDestBearingRef','GPSDestBearing','GPSDestDistanceRef','GPSDestDistance','GPSProcessingMethod','GPSAreaInformation','GPSDateStamp','GPSDifferential']
for k, v in info.items():
print(gps_keys[k]+": "+str(v))
else:
print("No GPS data present")
img = Image.open('20191002_151243_137.TIFF')
exif = img.getexif()
print_gps_data(exif)
img.save("out.TIFF", exif=exif)
print()
img = Image.open('out.TIFF')
exif = img.getexif()
print_gps_data(exif)
What did you do?
Tried to access TIFF tags with the Pillow library but get nothing.
I can upload my .tiff file to https://exifinfo.org/ and see many tags.
What did you expect to happen?
To be able to access exif tags of my tiff files.
What actually happened?
An empty dict is returned.
What are your OS, Python and Pillow versions?