mirror of
https://github.com/python-pillow/Pillow.git
synced 2024-12-24 17:06:16 +03:00
Read Photoshop resolution data
This commit is contained in:
parent
975fccafc7
commit
636ad68f5e
|
@ -590,6 +590,15 @@ class TestFileJpeg(PillowTestCase):
|
|||
# Act / Assert
|
||||
self.assertEqual(im._getexif()[306], '2017:03:13 23:03:09')
|
||||
|
||||
def test_photoshop(self):
|
||||
im = Image.open("Tests/images/photoshop-200dpi.jpg")
|
||||
self.assertEqual(im.info["photoshop"][0x03ed], {
|
||||
'XResolution': 200.0,
|
||||
'DisplayedUnitsX': 1,
|
||||
'YResolution': 200.0,
|
||||
'DisplayedUnitsY': 1,
|
||||
})
|
||||
|
||||
|
||||
@unittest.skipUnless(sys.platform.startswith('win32'), "Windows only")
|
||||
class TestFileCloseW32(PillowTestCase):
|
||||
|
|
|
@ -198,35 +198,9 @@ def getiptcinfo(im):
|
|||
|
||||
elif isinstance(im, JpegImagePlugin.JpegImageFile):
|
||||
# extract the IPTC/NAA resource
|
||||
try:
|
||||
app = im.app["APP13"]
|
||||
if app[:14] == b"Photoshop 3.0\x00":
|
||||
app = app[14:]
|
||||
# parse the image resource block
|
||||
offset = 0
|
||||
while app[offset:offset+4] == b"8BIM":
|
||||
offset += 4
|
||||
# resource code
|
||||
code = i16(app, offset)
|
||||
offset += 2
|
||||
# resource name (usually empty)
|
||||
name_len = i8(app[offset])
|
||||
# name = app[offset+1:offset+1+name_len]
|
||||
offset = 1 + offset + name_len
|
||||
if offset & 1:
|
||||
offset += 1
|
||||
# resource data block
|
||||
size = i32(app, offset)
|
||||
offset += 4
|
||||
if code == 0x0404:
|
||||
# 0x0404 contains IPTC/NAA data
|
||||
data = app[offset:offset+size]
|
||||
break
|
||||
offset = offset + size
|
||||
if offset & 1:
|
||||
offset += 1
|
||||
except (AttributeError, KeyError):
|
||||
pass
|
||||
photoshop = im.info.get("photoshop")
|
||||
if photoshop:
|
||||
data = photoshop.get(0x0404)
|
||||
|
||||
elif isinstance(im, TiffImagePlugin.TiffImageFile):
|
||||
# get raw data from the IPTC/NAA tag (PhotoShop tags the data
|
||||
|
|
|
@ -39,7 +39,7 @@ import struct
|
|||
import io
|
||||
import warnings
|
||||
from . import Image, ImageFile, TiffImagePlugin
|
||||
from ._binary import i8, o8, i16be as i16
|
||||
from ._binary import i8, o8, i16be as i16, i32be as i32
|
||||
from .JpegPresets import presets
|
||||
from ._util import isStringType
|
||||
|
||||
|
@ -104,6 +104,39 @@ def APP(self, marker):
|
|||
# reassemble the profile, rather than assuming that the APP2
|
||||
# markers appear in the correct sequence.
|
||||
self.icclist.append(s)
|
||||
elif marker == 0xFFED:
|
||||
if s[:14] == b"Photoshop 3.0\x00":
|
||||
blocks = s[14:]
|
||||
# parse the image resource block
|
||||
offset = 0
|
||||
photoshop = {}
|
||||
while blocks[offset:offset+4] == b"8BIM":
|
||||
offset += 4
|
||||
# resource code
|
||||
code = i16(blocks, offset)
|
||||
offset += 2
|
||||
# resource name (usually empty)
|
||||
name_len = i8(blocks[offset])
|
||||
# name = blocks[offset+1:offset+1+name_len]
|
||||
offset = 1 + offset + name_len
|
||||
if offset & 1:
|
||||
offset += 1
|
||||
# resource data block
|
||||
size = i32(blocks, offset)
|
||||
offset += 4
|
||||
data = blocks[offset:offset+size]
|
||||
if code == 0x03ED: # ResolutionInfo
|
||||
data = {
|
||||
'XResolution': i32(data[:4]) / 65536,
|
||||
'DisplayedUnitsX': i16(data[4:8]),
|
||||
'YResolution': i32(data[8:12]) / 65536,
|
||||
'DisplayedUnitsY': i16(data[12:]),
|
||||
}
|
||||
photoshop[code] = data
|
||||
offset = offset + size
|
||||
if offset & 1:
|
||||
offset += 1
|
||||
self.info["photoshop"] = photoshop
|
||||
elif marker == 0xFFEE and s[:5] == b"Adobe":
|
||||
self.info["adobe"] = i16(s, 5)
|
||||
# extract Adobe custom properties
|
||||
|
|
Loading…
Reference in New Issue
Block a user