mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-24 17:06:16 +03:00
Allow get_child_images to access JPEG thumbnails
This commit is contained in:
parent
8ada23ed04
commit
c2a42655e1
BIN
Tests/images/flower_thumbnail.png
Normal file
BIN
Tests/images/flower_thumbnail.png
Normal file
Binary file not shown.
After Width: | Height: | Size: 35 KiB |
|
@ -415,6 +415,13 @@ class TestFileJpeg:
|
|||
info = im._getexif()
|
||||
assert info[305] == "Adobe Photoshop CS Macintosh"
|
||||
|
||||
def test_get_child_images(self):
|
||||
with Image.open("Tests/images/flower.jpg") as im:
|
||||
ims = im.get_child_images()
|
||||
|
||||
assert len(ims) == 1
|
||||
assert_image_equal_tofile(ims[0], "Tests/images/flower_thumbnail.png")
|
||||
|
||||
def test_mp(self):
|
||||
with Image.open("Tests/images/pil_sample_rgb.jpg") as im:
|
||||
assert im._getmp() is None
|
||||
|
|
|
@ -1454,6 +1454,49 @@ class Image:
|
|||
self._exif._loaded = False
|
||||
self.getexif()
|
||||
|
||||
def get_child_images(self):
|
||||
child_images = []
|
||||
exif = self.getexif()
|
||||
ifds = []
|
||||
if ExifTags.Base.SubIFDs in exif:
|
||||
subifd_offsets = exif[ExifTags.Base.SubIFDs]
|
||||
if subifd_offsets:
|
||||
if not isinstance(subifd_offsets, tuple):
|
||||
subifd_offsets = (subifd_offsets,)
|
||||
for subifd_offset in subifd_offsets:
|
||||
ifds.append((exif._get_ifd_dict(subifd_offset), subifd_offset))
|
||||
ifd1 = exif.get_ifd(ExifTags.IFD.IFD1)
|
||||
if ifd1 and ifd1.get(513):
|
||||
ifds.append((ifd1, exif._info.next))
|
||||
|
||||
offset = None
|
||||
for ifd, ifd_offset in ifds:
|
||||
current_offset = self.fp.tell()
|
||||
if offset is None:
|
||||
offset = current_offset
|
||||
|
||||
fp = self.fp
|
||||
thumbnailOffset = ifd.get(513)
|
||||
if thumbnailOffset is not None:
|
||||
try:
|
||||
thumbnailOffset += self._exif_offset
|
||||
except AttributeError:
|
||||
pass
|
||||
self.fp.seek(thumbnailOffset)
|
||||
data = self.fp.read(ifd.get(514))
|
||||
fp = io.BytesIO(data)
|
||||
|
||||
with open(fp) as im:
|
||||
if thumbnailOffset is None:
|
||||
im._frame_pos = [ifd_offset]
|
||||
im._seek(0)
|
||||
im.load()
|
||||
child_images.append(im)
|
||||
|
||||
if offset is not None:
|
||||
self.fp.seek(offset)
|
||||
return child_images
|
||||
|
||||
def getim(self):
|
||||
"""
|
||||
Returns a capsule that points to the internal image memory.
|
||||
|
|
|
@ -89,6 +89,7 @@ def APP(self, marker):
|
|||
if "exif" not in self.info:
|
||||
# extract EXIF information (incomplete)
|
||||
self.info["exif"] = s # FIXME: value will change
|
||||
self._exif_offset = self.fp.tell() - n + 6
|
||||
elif marker == 0xFFE2 and s[:5] == b"FPXR\0":
|
||||
# extract FlashPix information (incomplete)
|
||||
self.info["flashpix"] = s # FIXME: value will change
|
||||
|
|
|
@ -1153,39 +1153,6 @@ class TiffImageFile(ImageFile.ImageFile):
|
|||
"""Return the current frame number"""
|
||||
return self.__frame
|
||||
|
||||
def get_child_images(self):
|
||||
if SUBIFD not in self.tag_v2:
|
||||
return []
|
||||
child_images = []
|
||||
exif = self.getexif()
|
||||
offset = None
|
||||
for im_offset in self.tag_v2[SUBIFD]:
|
||||
# reset buffered io handle in case fp
|
||||
# was passed to libtiff, invalidating the buffer
|
||||
current_offset = self._fp.tell()
|
||||
if offset is None:
|
||||
offset = current_offset
|
||||
|
||||
fp = self._fp
|
||||
ifd = exif._get_ifd_dict(im_offset)
|
||||
jpegInterchangeFormat = ifd.get(513)
|
||||
if jpegInterchangeFormat is not None:
|
||||
fp.seek(jpegInterchangeFormat)
|
||||
jpeg_data = fp.read(ifd.get(514))
|
||||
|
||||
fp = io.BytesIO(jpeg_data)
|
||||
|
||||
with Image.open(fp) as im:
|
||||
if jpegInterchangeFormat is None:
|
||||
im._frame_pos = [im_offset]
|
||||
im._seek(0)
|
||||
im.load()
|
||||
child_images.append(im)
|
||||
|
||||
if offset is not None:
|
||||
self._fp.seek(offset)
|
||||
return child_images
|
||||
|
||||
def getxmp(self):
|
||||
"""
|
||||
Returns a dictionary containing the XMP tags.
|
||||
|
|
Loading…
Reference in New Issue
Block a user