mirror of
				https://github.com/python-pillow/Pillow.git
				synced 2025-11-04 01:47:47 +03:00 
			
		
		
		
	Merge pull request #565 from al45tair/icns-support
Improved icns support
This commit is contained in:
		
						commit
						6e6bc21ba1
					
				
							
								
								
									
										
											BIN
										
									
								
								Images/pillow.icns
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Images/pillow.icns
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Images/pillow.ico
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Images/pillow.ico
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							| 
		 After Width: | Height: | Size: 100 KiB  | 
| 
						 | 
					@ -10,12 +10,17 @@
 | 
				
			||||||
# Copyright (c) 2004 by Bob Ippolito.
 | 
					# Copyright (c) 2004 by Bob Ippolito.
 | 
				
			||||||
# Copyright (c) 2004 by Secret Labs.
 | 
					# Copyright (c) 2004 by Secret Labs.
 | 
				
			||||||
# Copyright (c) 2004 by Fredrik Lundh.
 | 
					# Copyright (c) 2004 by Fredrik Lundh.
 | 
				
			||||||
 | 
					# Copyright (c) 2014 by Alastair Houghton.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
# See the README file for information on usage and redistribution.
 | 
					# See the README file for information on usage and redistribution.
 | 
				
			||||||
#
 | 
					#
 | 
				
			||||||
 | 
					
 | 
				
			||||||
from PIL import Image, ImageFile, _binary
 | 
					from PIL import Image, ImageFile, PngImagePlugin, _binary
 | 
				
			||||||
import struct
 | 
					import struct, io
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enable_jpeg2k = hasattr(Image.core, 'jp2klib_version')
 | 
				
			||||||
 | 
					if enable_jpeg2k:
 | 
				
			||||||
 | 
					    from PIL import Jpeg2KImagePlugin
 | 
				
			||||||
 | 
					
 | 
				
			||||||
i8 = _binary.i8
 | 
					i8 = _binary.i8
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					@ -40,14 +45,15 @@ def read_32(fobj, start_length, size):
 | 
				
			||||||
    """
 | 
					    """
 | 
				
			||||||
    (start, length) = start_length
 | 
					    (start, length) = start_length
 | 
				
			||||||
    fobj.seek(start)
 | 
					    fobj.seek(start)
 | 
				
			||||||
    sizesq = size[0] * size[1]
 | 
					    pixel_size = (size[0] * size[2], size[1] * size[2])
 | 
				
			||||||
 | 
					    sizesq = pixel_size[0] * pixel_size[1]
 | 
				
			||||||
    if length == sizesq * 3:
 | 
					    if length == sizesq * 3:
 | 
				
			||||||
        # uncompressed ("RGBRGBGB")
 | 
					        # uncompressed ("RGBRGBGB")
 | 
				
			||||||
        indata = fobj.read(length)
 | 
					        indata = fobj.read(length)
 | 
				
			||||||
        im = Image.frombuffer("RGB", size, indata, "raw", "RGB", 0, 1)
 | 
					        im = Image.frombuffer("RGB", pixel_size, indata, "raw", "RGB", 0, 1)
 | 
				
			||||||
    else:
 | 
					    else:
 | 
				
			||||||
        # decode image
 | 
					        # decode image
 | 
				
			||||||
        im = Image.new("RGB", size, None)
 | 
					        im = Image.new("RGB", pixel_size, None)
 | 
				
			||||||
        for band_ix in range(3):
 | 
					        for band_ix in range(3):
 | 
				
			||||||
            data = []
 | 
					            data = []
 | 
				
			||||||
            bytesleft = sizesq
 | 
					            bytesleft = sizesq
 | 
				
			||||||
| 
						 | 
					@ -72,7 +78,7 @@ def read_32(fobj, start_length, size):
 | 
				
			||||||
                    "Error reading channel [%r left]" % bytesleft
 | 
					                    "Error reading channel [%r left]" % bytesleft
 | 
				
			||||||
                    )
 | 
					                    )
 | 
				
			||||||
            band = Image.frombuffer(
 | 
					            band = Image.frombuffer(
 | 
				
			||||||
                "L", size, b"".join(data), "raw", "L", 0, 1
 | 
					                "L", pixel_size, b"".join(data), "raw", "L", 0, 1
 | 
				
			||||||
                )
 | 
					                )
 | 
				
			||||||
            im.im.putband(band.im, band_ix)
 | 
					            im.im.putband(band.im, band_ix)
 | 
				
			||||||
    return {"RGB": im}
 | 
					    return {"RGB": im}
 | 
				
			||||||
| 
						 | 
					@ -81,27 +87,80 @@ def read_mk(fobj, start_length, size):
 | 
				
			||||||
    # Alpha masks seem to be uncompressed
 | 
					    # Alpha masks seem to be uncompressed
 | 
				
			||||||
    (start, length) = start_length
 | 
					    (start, length) = start_length
 | 
				
			||||||
    fobj.seek(start)
 | 
					    fobj.seek(start)
 | 
				
			||||||
 | 
					    pixel_size = (size[0] * size[2], size[1] * size[2])
 | 
				
			||||||
 | 
					    sizesq = pixel_size[0] * pixel_size[1]
 | 
				
			||||||
    band = Image.frombuffer(
 | 
					    band = Image.frombuffer(
 | 
				
			||||||
        "L", size, fobj.read(size[0]*size[1]), "raw", "L", 0, 1
 | 
					        "L", pixel_size, fobj.read(sizesq), "raw", "L", 0, 1
 | 
				
			||||||
        )
 | 
					        )
 | 
				
			||||||
    return {"A": band}
 | 
					    return {"A": band}
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def read_png_or_jpeg2000(fobj, start_length, size):
 | 
				
			||||||
 | 
					    (start, length) = start_length
 | 
				
			||||||
 | 
					    fobj.seek(start)
 | 
				
			||||||
 | 
					    sig = fobj.read(12)
 | 
				
			||||||
 | 
					    if sig[:8] == b'\x89PNG\x0d\x0a\x1a\x0a':
 | 
				
			||||||
 | 
					        fobj.seek(start)
 | 
				
			||||||
 | 
					        im = PngImagePlugin.PngImageFile(fobj)
 | 
				
			||||||
 | 
					        return {"RGBA": im}
 | 
				
			||||||
 | 
					    elif sig[:4] == b'\xff\x4f\xff\x51' \
 | 
				
			||||||
 | 
					        or sig[:4] == b'\x0d\x0a\x87\x0a' \
 | 
				
			||||||
 | 
					        or sig == b'\x00\x00\x00\x0cjP  \x0d\x0a\x87\x0a':
 | 
				
			||||||
 | 
					        if not enable_jpeg2k:
 | 
				
			||||||
 | 
					            raise ValueError('Unsupported icon subimage format (rebuild PIL with JPEG 2000 support to fix this)')
 | 
				
			||||||
 | 
					        # j2k, jpc or j2c
 | 
				
			||||||
 | 
					        fobj.seek(start)
 | 
				
			||||||
 | 
					        jp2kstream = fobj.read(length)
 | 
				
			||||||
 | 
					        f = io.BytesIO(jp2kstream)
 | 
				
			||||||
 | 
					        im = Jpeg2KImagePlugin.Jpeg2KImageFile(f)
 | 
				
			||||||
 | 
					        if im.mode != 'RGBA':
 | 
				
			||||||
 | 
					            im = im.convert('RGBA')
 | 
				
			||||||
 | 
					        return {"RGBA": im}
 | 
				
			||||||
 | 
					    else:
 | 
				
			||||||
 | 
					        raise ValueError('Unsupported icon subimage format')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
class IcnsFile:
 | 
					class IcnsFile:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    SIZES = {
 | 
					    SIZES = {
 | 
				
			||||||
        (128, 128): [
 | 
					        (512, 512, 2): [
 | 
				
			||||||
 | 
					            (b'ic10', read_png_or_jpeg2000),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        (512, 512, 1): [
 | 
				
			||||||
 | 
					            (b'ic09', read_png_or_jpeg2000),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        (256, 256, 2): [
 | 
				
			||||||
 | 
					            (b'ic14', read_png_or_jpeg2000),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        (256, 256, 1): [
 | 
				
			||||||
 | 
					            (b'ic08', read_png_or_jpeg2000),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        (128, 128, 2): [
 | 
				
			||||||
 | 
					            (b'ic13', read_png_or_jpeg2000),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        (128, 128, 1): [
 | 
				
			||||||
 | 
					            (b'ic07', read_png_or_jpeg2000),
 | 
				
			||||||
            (b'it32', read_32t),
 | 
					            (b'it32', read_32t),
 | 
				
			||||||
            (b't8mk', read_mk),
 | 
					            (b't8mk', read_mk),
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        (48, 48): [
 | 
					        (64, 64, 1): [
 | 
				
			||||||
 | 
					            (b'icp6', read_png_or_jpeg2000),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        (32, 32, 2): [
 | 
				
			||||||
 | 
					            (b'ic12', read_png_or_jpeg2000),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        (48, 48, 1): [
 | 
				
			||||||
            (b'ih32', read_32),
 | 
					            (b'ih32', read_32),
 | 
				
			||||||
            (b'h8mk', read_mk),
 | 
					            (b'h8mk', read_mk),
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        (32, 32): [
 | 
					        (32, 32, 1): [
 | 
				
			||||||
 | 
					            (b'icp5', read_png_or_jpeg2000),
 | 
				
			||||||
            (b'il32', read_32),
 | 
					            (b'il32', read_32),
 | 
				
			||||||
            (b'l8mk', read_mk),
 | 
					            (b'l8mk', read_mk),
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
        (16, 16): [
 | 
					        (16, 16, 2): [
 | 
				
			||||||
 | 
					            (b'ic11', read_png_or_jpeg2000),
 | 
				
			||||||
 | 
					        ],
 | 
				
			||||||
 | 
					        (16, 16, 1): [
 | 
				
			||||||
 | 
					            (b'icp4', read_png_or_jpeg2000),
 | 
				
			||||||
            (b'is32', read_32),
 | 
					            (b'is32', read_32),
 | 
				
			||||||
            (b's8mk', read_mk),
 | 
					            (b's8mk', read_mk),
 | 
				
			||||||
        ],
 | 
					        ],
 | 
				
			||||||
| 
						 | 
					@ -115,7 +174,7 @@ class IcnsFile:
 | 
				
			||||||
        self.dct = dct = {}
 | 
					        self.dct = dct = {}
 | 
				
			||||||
        self.fobj = fobj
 | 
					        self.fobj = fobj
 | 
				
			||||||
        sig, filesize = nextheader(fobj)
 | 
					        sig, filesize = nextheader(fobj)
 | 
				
			||||||
        if sig != 'icns':
 | 
					        if sig != b'icns':
 | 
				
			||||||
            raise SyntaxError('not an icns file')
 | 
					            raise SyntaxError('not an icns file')
 | 
				
			||||||
        i = HEADERSIZE
 | 
					        i = HEADERSIZE
 | 
				
			||||||
        while i < filesize:
 | 
					        while i < filesize:
 | 
				
			||||||
| 
						 | 
					@ -157,7 +216,14 @@ class IcnsFile:
 | 
				
			||||||
    def getimage(self, size=None):
 | 
					    def getimage(self, size=None):
 | 
				
			||||||
        if size is None:
 | 
					        if size is None:
 | 
				
			||||||
            size = self.bestsize()
 | 
					            size = self.bestsize()
 | 
				
			||||||
 | 
					        if len(size) == 2:
 | 
				
			||||||
 | 
					            size = (size[0], size[1], 1)
 | 
				
			||||||
        channels = self.dataforsize(size)
 | 
					        channels = self.dataforsize(size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        im = channels.get('RGBA', None)
 | 
				
			||||||
 | 
					        if im:
 | 
				
			||||||
 | 
					            return im
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        im = channels.get("RGB").copy()
 | 
					        im = channels.get("RGB").copy()
 | 
				
			||||||
        try:
 | 
					        try:
 | 
				
			||||||
            im.putalpha(channels["A"])
 | 
					            im.putalpha(channels["A"])
 | 
				
			||||||
| 
						 | 
					@ -185,18 +251,29 @@ class IcnsImageFile(ImageFile.ImageFile):
 | 
				
			||||||
    def _open(self):
 | 
					    def _open(self):
 | 
				
			||||||
        self.icns = IcnsFile(self.fp)
 | 
					        self.icns = IcnsFile(self.fp)
 | 
				
			||||||
        self.mode = 'RGBA'
 | 
					        self.mode = 'RGBA'
 | 
				
			||||||
        self.size = self.icns.bestsize()
 | 
					        self.best_size = self.icns.bestsize()
 | 
				
			||||||
 | 
					        self.size = (self.best_size[0] * self.best_size[2],
 | 
				
			||||||
 | 
					                     self.best_size[1] * self.best_size[2])
 | 
				
			||||||
        self.info['sizes'] = self.icns.itersizes()
 | 
					        self.info['sizes'] = self.icns.itersizes()
 | 
				
			||||||
        # Just use this to see if it's loaded or not yet.
 | 
					        # Just use this to see if it's loaded or not yet.
 | 
				
			||||||
        self.tile = ('',)
 | 
					        self.tile = ('',)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
    def load(self):
 | 
					    def load(self):
 | 
				
			||||||
 | 
					        if len(self.size) == 3:
 | 
				
			||||||
 | 
					            self.best_size = self.size
 | 
				
			||||||
 | 
					            self.size = (self.best_size[0] * self.best_size[2],
 | 
				
			||||||
 | 
					                         self.best_size[1] * self.best_size[2])
 | 
				
			||||||
 | 
					
 | 
				
			||||||
        Image.Image.load(self)
 | 
					        Image.Image.load(self)
 | 
				
			||||||
        if not self.tile:
 | 
					        if not self.tile:
 | 
				
			||||||
            return
 | 
					            return
 | 
				
			||||||
        self.load_prepare()
 | 
					        self.load_prepare()
 | 
				
			||||||
        # This is likely NOT the best way to do it, but whatever.
 | 
					        # This is likely NOT the best way to do it, but whatever.
 | 
				
			||||||
        im = self.icns.getimage(self.size)
 | 
					        im = self.icns.getimage(self.best_size)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					        # If this is a PNG or JPEG 2000, it won't be loaded yet
 | 
				
			||||||
 | 
					        im.load()
 | 
				
			||||||
 | 
					        
 | 
				
			||||||
        self.im = im.im
 | 
					        self.im = im.im
 | 
				
			||||||
        self.mode = im.mode
 | 
					        self.mode = im.mode
 | 
				
			||||||
        self.size = im.size
 | 
					        self.size = im.size
 | 
				
			||||||
| 
						 | 
					@ -205,12 +282,18 @@ class IcnsImageFile(ImageFile.ImageFile):
 | 
				
			||||||
        self.tile = ()
 | 
					        self.tile = ()
 | 
				
			||||||
        self.load_end()
 | 
					        self.load_end()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					 | 
				
			||||||
Image.register_open("ICNS", IcnsImageFile, lambda x: x[:4] == b'icns')
 | 
					Image.register_open("ICNS", IcnsImageFile, lambda x: x[:4] == b'icns')
 | 
				
			||||||
Image.register_extension("ICNS", '.icns')
 | 
					Image.register_extension("ICNS", '.icns')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
if __name__ == '__main__':
 | 
					if __name__ == '__main__':
 | 
				
			||||||
    import os, sys
 | 
					    import os, sys
 | 
				
			||||||
 | 
					    imf = IcnsImageFile(open(sys.argv[1], 'rb'))
 | 
				
			||||||
 | 
					    for size in imf.info['sizes']:
 | 
				
			||||||
 | 
					        imf.size = size
 | 
				
			||||||
 | 
					        imf.load()
 | 
				
			||||||
 | 
					        im = imf.im
 | 
				
			||||||
 | 
					        im.save('out-%s-%s-%s.png' % size)
 | 
				
			||||||
    im = Image.open(open(sys.argv[1], "rb"))
 | 
					    im = Image.open(open(sys.argv[1], "rb"))
 | 
				
			||||||
    im.save("out.png")
 | 
					    im.save("out.png")
 | 
				
			||||||
 | 
					    if sys.platform == 'windows':
 | 
				
			||||||
        os.startfile("out.png")
 | 
					        os.startfile("out.png")
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
							
								
								
									
										
											BIN
										
									
								
								Tests/images/pillow2.icns
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/pillow2.icns
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										
											BIN
										
									
								
								Tests/images/pillow3.icns
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										
											BIN
										
									
								
								Tests/images/pillow3.icns
									
									
									
									
									
										Normal file
									
								
							
										
											Binary file not shown.
										
									
								
							
							
								
								
									
										66
									
								
								Tests/test_file_icns.py
									
									
									
									
									
										Normal file
									
								
							
							
						
						
									
										66
									
								
								Tests/test_file_icns.py
									
									
									
									
									
										Normal file
									
								
							| 
						 | 
					@ -0,0 +1,66 @@
 | 
				
			||||||
 | 
					from tester import *
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					from PIL import Image
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					# sample icon file
 | 
				
			||||||
 | 
					file = "Images/pillow.icns"
 | 
				
			||||||
 | 
					data = open(file, "rb").read()
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					enable_jpeg2k = hasattr(Image.core, 'jp2klib_version')
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_sanity():
 | 
				
			||||||
 | 
					    # Loading this icon by default should result in the largest size
 | 
				
			||||||
 | 
					    # (512x512@2x) being loaded
 | 
				
			||||||
 | 
					    im = Image.open(file)
 | 
				
			||||||
 | 
					    im.load()
 | 
				
			||||||
 | 
					    assert_equal(im.mode, "RGBA")
 | 
				
			||||||
 | 
					    assert_equal(im.size, (1024, 1024))
 | 
				
			||||||
 | 
					    assert_equal(im.format, "ICNS")
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_sizes():
 | 
				
			||||||
 | 
					    # Check that we can load all of the sizes, and that the final pixel
 | 
				
			||||||
 | 
					    # dimensions are as expected
 | 
				
			||||||
 | 
					    im = Image.open(file)
 | 
				
			||||||
 | 
					    for w,h,r in im.info['sizes']:
 | 
				
			||||||
 | 
					        wr = w * r
 | 
				
			||||||
 | 
					        hr = h * r
 | 
				
			||||||
 | 
					        im2 = Image.open(file)
 | 
				
			||||||
 | 
					        im2.size = (w, h, r)
 | 
				
			||||||
 | 
					        im2.load()
 | 
				
			||||||
 | 
					        assert_equal(im2.mode, 'RGBA')
 | 
				
			||||||
 | 
					        assert_equal(im2.size, (wr, hr))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_older_icon():
 | 
				
			||||||
 | 
					    # This icon was made with Icon Composer rather than iconutil; it still
 | 
				
			||||||
 | 
					    # uses PNG rather than JP2, however (since it was made on 10.9).
 | 
				
			||||||
 | 
					    im = Image.open('Tests/images/pillow2.icns')
 | 
				
			||||||
 | 
					    for w,h,r in im.info['sizes']:
 | 
				
			||||||
 | 
					        wr = w * r
 | 
				
			||||||
 | 
					        hr = h * r
 | 
				
			||||||
 | 
					        im2 = Image.open('Tests/images/pillow2.icns')
 | 
				
			||||||
 | 
					        im2.size = (w, h, r)
 | 
				
			||||||
 | 
					        im2.load()
 | 
				
			||||||
 | 
					        assert_equal(im2.mode, 'RGBA')
 | 
				
			||||||
 | 
					        assert_equal(im2.size, (wr, hr))
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					def test_jp2_icon():
 | 
				
			||||||
 | 
					    # This icon was made by using Uli Kusterer's oldiconutil to replace
 | 
				
			||||||
 | 
					    # the PNG images with JPEG 2000 ones.  The advantage of doing this is
 | 
				
			||||||
 | 
					    # that OS X 10.5 supports JPEG 2000 but not PNG; some commercial
 | 
				
			||||||
 | 
					    # software therefore does just this.
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    # (oldiconutil is here: https://github.com/uliwitness/oldiconutil)
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					    if not enable_jpeg2k:
 | 
				
			||||||
 | 
					        return
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
 | 
					    im = Image.open('Tests/images/pillow3.icns')
 | 
				
			||||||
 | 
					    for w,h,r in im.info['sizes']:
 | 
				
			||||||
 | 
					        wr = w * r
 | 
				
			||||||
 | 
					        hr = h * r
 | 
				
			||||||
 | 
					        im2 = Image.open('Tests/images/pillow3.icns')
 | 
				
			||||||
 | 
					        im2.size = (w, h, r)
 | 
				
			||||||
 | 
					        im2.load()
 | 
				
			||||||
 | 
					        assert_equal(im2.mode, 'RGBA')
 | 
				
			||||||
 | 
					        assert_equal(im2.size, (wr, hr))
 | 
				
			||||||
 | 
					    
 | 
				
			||||||
| 
						 | 
					@ -523,6 +523,25 @@ ICO
 | 
				
			||||||
 | 
					
 | 
				
			||||||
ICO is used to store icons on Windows. The largest available icon is read.
 | 
					ICO is used to store icons on Windows. The largest available icon is read.
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					ICNS
 | 
				
			||||||
 | 
					^^^^
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					PIL reads Mac OS X ``.icns`` files.  By default, the largest available icon is
 | 
				
			||||||
 | 
					read, though you can override this by setting the :py:attr:`~PIL.Image.Image.size`
 | 
				
			||||||
 | 
					property before calling :py:meth:`~PIL.Image.Image.load`.  The
 | 
				
			||||||
 | 
					:py:meth:`~PIL.Image.Image.open` method sets the following
 | 
				
			||||||
 | 
					:py:attr:`~PIL.Image.Image.info` property:
 | 
				
			||||||
 | 
					
 | 
				
			||||||
 | 
					**sizes**
 | 
				
			||||||
 | 
					    A list of supported sizes found in this icon file; these are a
 | 
				
			||||||
 | 
					    3-tuple, ``(width, height, scale)``, where ``scale`` is 2 for a retina
 | 
				
			||||||
 | 
					    icon and 1 for a standard icon.  You *are* permitted to use this 3-tuple
 | 
				
			||||||
 | 
					    format for the :py:attr:`~PIL.Image.Image.size` property if you set it
 | 
				
			||||||
 | 
					    before calling :py:meth:`~PIL.Image.Image.load`; after loading, the size
 | 
				
			||||||
 | 
					    will be reset to a 2-tuple containing pixel dimensions (so, e.g. if you
 | 
				
			||||||
 | 
					    ask for ``(512, 512, 2)``, the final value of
 | 
				
			||||||
 | 
					    :py:attr:`~PIL.Image.Image.size` will be ``(1024, 1024)``).
 | 
				
			||||||
 | 
					
 | 
				
			||||||
IMT
 | 
					IMT
 | 
				
			||||||
^^^
 | 
					^^^
 | 
				
			||||||
 | 
					
 | 
				
			||||||
| 
						 | 
					
 | 
				
			||||||
		Loading…
	
		Reference in New Issue
	
	Block a user