mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-08-09 23:04:45 +03:00
Merge 2d53be5a47
into d46441b789
This commit is contained in:
commit
af18cc8207
|
@ -17,7 +17,17 @@
|
||||||
|
|
||||||
from PIL import Image, ImageFile, PngImagePlugin, _binary
|
from PIL import Image, ImageFile, PngImagePlugin, _binary
|
||||||
import io
|
import io
|
||||||
|
import sys
|
||||||
|
import os
|
||||||
import struct
|
import struct
|
||||||
|
import tempfile
|
||||||
|
import subprocess
|
||||||
|
import shutil
|
||||||
|
|
||||||
|
try:
|
||||||
|
import warnings
|
||||||
|
except ImportError:
|
||||||
|
warnings = None
|
||||||
|
|
||||||
enable_jpeg2k = hasattr(Image.core, 'jp2klib_version')
|
enable_jpeg2k = hasattr(Image.core, 'jp2klib_version')
|
||||||
if enable_jpeg2k:
|
if enable_jpeg2k:
|
||||||
|
@ -28,6 +38,49 @@ i8 = _binary.i8
|
||||||
HEADERSIZE = 8
|
HEADERSIZE = 8
|
||||||
|
|
||||||
|
|
||||||
|
def _save(im, fp, filename):
|
||||||
|
if sys.platform == 'darwin':
|
||||||
|
tmp_icons_dir = tempfile.mkdtemp(suffix='.iconset')
|
||||||
|
tmp_targe_handle, tmp_targe_path = tempfile.mkstemp(suffix='.icns')
|
||||||
|
tmp_targe_file = None
|
||||||
|
os.close(tmp_targe_handle)
|
||||||
|
try:
|
||||||
|
sizes = im.encoderinfo.get("sizes",
|
||||||
|
[(16, 16, 1), (16, 16, 2),
|
||||||
|
(32, 32, 1), (32, 32, 2),
|
||||||
|
(128, 128, 1), (128, 128, 2),
|
||||||
|
(256, 256, 1), (256, 256, 2),
|
||||||
|
(512, 512, 1), (512, 512, 2)])
|
||||||
|
for size in sizes:
|
||||||
|
width, height, scale = size
|
||||||
|
size_name = '%sx%s%s' % (width, height,
|
||||||
|
'' if scale == 1 else
|
||||||
|
('@%sx' % scale))
|
||||||
|
if im.size[0] < width*scale or im.size[1] < height*scale:
|
||||||
|
if warnings:
|
||||||
|
warnings.warn(('Skip %s because original image ' +
|
||||||
|
'size(%sx%s) is too small') %
|
||||||
|
(size_name, im.size[0], im.size[1]))
|
||||||
|
continue
|
||||||
|
png_path = os.path.join(tmp_icons_dir,
|
||||||
|
'icon_%s.png' % size_name)
|
||||||
|
with open(png_path, 'wb') as png_file:
|
||||||
|
tmp = im.copy()
|
||||||
|
tmp.thumbnail((width*scale, height*scale), Image.LANCZOS)
|
||||||
|
tmp.save(png_file, "png")
|
||||||
|
subprocess.call(['iconutil', '--convert', 'icns', '--output',
|
||||||
|
tmp_targe_path, tmp_icons_dir])
|
||||||
|
with open(tmp_targe_path, 'rb') as tmp_targe_file:
|
||||||
|
fp.write(tmp_targe_file.read())
|
||||||
|
finally:
|
||||||
|
if tmp_targe_file:
|
||||||
|
tmp_targe_file.close()
|
||||||
|
os.remove(tmp_targe_path)
|
||||||
|
shutil.rmtree(tmp_icons_dir)
|
||||||
|
else:
|
||||||
|
raise RuntimeError("Unsupported in non-darwin platform")
|
||||||
|
|
||||||
|
|
||||||
def nextheader(fobj):
|
def nextheader(fobj):
|
||||||
return struct.unpack('>4sI', fobj.read(HEADERSIZE))
|
return struct.unpack('>4sI', fobj.read(HEADERSIZE))
|
||||||
|
|
||||||
|
@ -294,8 +347,10 @@ class IcnsImageFile(ImageFile.ImageFile):
|
||||||
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_save("ICNS", _save)
|
||||||
Image.register_extension("ICNS", '.icns')
|
Image.register_extension("ICNS", '.icns')
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
import os
|
import os
|
||||||
import sys
|
import sys
|
||||||
|
|
|
@ -1,5 +1,6 @@
|
||||||
from helper import unittest, PillowTestCase
|
from helper import unittest, PillowTestCase, hopper
|
||||||
|
|
||||||
|
import io
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
# sample icon file
|
# sample icon file
|
||||||
|
@ -67,6 +68,27 @@ class TestFileIcns(PillowTestCase):
|
||||||
self.assertEqual(im2.mode, 'RGBA')
|
self.assertEqual(im2.mode, 'RGBA')
|
||||||
self.assertEqual(im2.size, (wr, hr))
|
self.assertEqual(im2.size, (wr, hr))
|
||||||
|
|
||||||
|
def test_save_to_bytes(self):
|
||||||
|
output = io.BytesIO()
|
||||||
|
im = hopper()
|
||||||
|
sizes = [(16, 16, 1), (16, 16, 2),
|
||||||
|
(32, 32, 1), (32, 32, 2),
|
||||||
|
(128, 128, 1)]
|
||||||
|
im.save(output, "icns", sizes=sizes)
|
||||||
|
output.seek(0)
|
||||||
|
reloaded = Image.open(output)
|
||||||
|
self.assertEqual(reloaded.mode, "RGBA")
|
||||||
|
self.assertEqual(reloaded.format, "ICNS")
|
||||||
|
self.assertEqual(set(reloaded.info['sizes']), set(sizes))
|
||||||
|
for w, h, r in reloaded.info['sizes']:
|
||||||
|
wr = w * r
|
||||||
|
hr = h * r
|
||||||
|
im2 = Image.open(file)
|
||||||
|
im2.size = (w, h, r)
|
||||||
|
im2.load()
|
||||||
|
self.assertEqual(im2.mode, 'RGBA')
|
||||||
|
self.assertEqual(im2.size, (wr, hr))
|
||||||
|
|
||||||
|
|
||||||
if __name__ == '__main__':
|
if __name__ == '__main__':
|
||||||
unittest.main()
|
unittest.main()
|
||||||
|
|
Loading…
Reference in New Issue
Block a user