mirror of
https://github.com/python-pillow/Pillow.git
synced 2025-05-01 14:33:40 +03:00
Merge pull request #5349 from latosha-maltba/master
This commit is contained in:
commit
8c852e44f0
|
@ -257,8 +257,23 @@ def netpbm_available():
|
||||||
return bool(shutil.which("ppmquant") and shutil.which("ppmtogif"))
|
return bool(shutil.which("ppmquant") and shutil.which("ppmtogif"))
|
||||||
|
|
||||||
|
|
||||||
def imagemagick_available():
|
def magick_command():
|
||||||
return bool(IMCONVERT and shutil.which(IMCONVERT))
|
if sys.platform == "win32":
|
||||||
|
magickhome = os.environ.get("MAGICK_HOME", "")
|
||||||
|
if magickhome:
|
||||||
|
imagemagick = [os.path.join(magickhome, "convert.exe")]
|
||||||
|
graphicsmagick = [os.path.join(magickhome, "gm.exe"), "convert"]
|
||||||
|
else:
|
||||||
|
imagemagick = None
|
||||||
|
graphicsmagick = None
|
||||||
|
else:
|
||||||
|
imagemagick = ["convert"]
|
||||||
|
graphicsmagick = ["gm", "convert"]
|
||||||
|
|
||||||
|
if imagemagick and shutil.which(imagemagick[0]):
|
||||||
|
return imagemagick
|
||||||
|
elif graphicsmagick and shutil.which(graphicsmagick[0]):
|
||||||
|
return graphicsmagick
|
||||||
|
|
||||||
|
|
||||||
def on_appveyor():
|
def on_appveyor():
|
||||||
|
@ -296,14 +311,6 @@ def is_mingw():
|
||||||
return sysconfig.get_platform() == "mingw"
|
return sysconfig.get_platform() == "mingw"
|
||||||
|
|
||||||
|
|
||||||
if sys.platform == "win32":
|
|
||||||
IMCONVERT = os.environ.get("MAGICK_HOME", "")
|
|
||||||
if IMCONVERT:
|
|
||||||
IMCONVERT = os.path.join(IMCONVERT, "convert.exe")
|
|
||||||
else:
|
|
||||||
IMCONVERT = "convert"
|
|
||||||
|
|
||||||
|
|
||||||
class cached_property:
|
class cached_property:
|
||||||
def __init__(self, func):
|
def __init__(self, func):
|
||||||
self.func = func
|
self.func = func
|
||||||
|
|
|
@ -5,9 +5,7 @@ import pytest
|
||||||
|
|
||||||
from PIL import Image
|
from PIL import Image
|
||||||
|
|
||||||
from .helper import IMCONVERT, assert_image_equal, hopper, imagemagick_available
|
from .helper import assert_image_equal, hopper, magick_command
|
||||||
|
|
||||||
_roundtrip = imagemagick_available()
|
|
||||||
|
|
||||||
|
|
||||||
def helper_save_as_palm(tmp_path, mode):
|
def helper_save_as_palm(tmp_path, mode):
|
||||||
|
@ -23,13 +21,10 @@ def helper_save_as_palm(tmp_path, mode):
|
||||||
assert os.path.getsize(outfile) > 0
|
assert os.path.getsize(outfile) > 0
|
||||||
|
|
||||||
|
|
||||||
def open_with_imagemagick(tmp_path, f):
|
def open_with_magick(magick, tmp_path, f):
|
||||||
if not imagemagick_available():
|
|
||||||
raise OSError()
|
|
||||||
|
|
||||||
outfile = str(tmp_path / "temp.png")
|
outfile = str(tmp_path / "temp.png")
|
||||||
rc = subprocess.call(
|
rc = subprocess.call(
|
||||||
[IMCONVERT, f, outfile], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT
|
magick + [f, outfile], stdout=subprocess.DEVNULL, stderr=subprocess.STDOUT
|
||||||
)
|
)
|
||||||
if rc:
|
if rc:
|
||||||
raise OSError
|
raise OSError
|
||||||
|
@ -37,14 +32,15 @@ def open_with_imagemagick(tmp_path, f):
|
||||||
|
|
||||||
|
|
||||||
def roundtrip(tmp_path, mode):
|
def roundtrip(tmp_path, mode):
|
||||||
if not _roundtrip:
|
magick = magick_command()
|
||||||
|
if not magick:
|
||||||
return
|
return
|
||||||
|
|
||||||
im = hopper(mode)
|
im = hopper(mode)
|
||||||
outfile = str(tmp_path / "temp.palm")
|
outfile = str(tmp_path / "temp.palm")
|
||||||
|
|
||||||
im.save(outfile)
|
im.save(outfile)
|
||||||
converted = open_with_imagemagick(tmp_path, outfile)
|
converted = open_with_magick(magick, tmp_path, outfile)
|
||||||
assert_image_equal(converted, im)
|
assert_image_equal(converted, im)
|
||||||
|
|
||||||
|
|
||||||
|
|
|
@ -18,6 +18,7 @@ All default viewers convert the image to be shown to PNG format.
|
||||||
The following viewers may be registered on Unix-based systems, if the given command is found:
|
The following viewers may be registered on Unix-based systems, if the given command is found:
|
||||||
|
|
||||||
.. autoclass:: PIL.ImageShow.DisplayViewer
|
.. autoclass:: PIL.ImageShow.DisplayViewer
|
||||||
|
.. autoclass:: PIL.ImageShow.GmDisplayViewer
|
||||||
.. autoclass:: PIL.ImageShow.EogViewer
|
.. autoclass:: PIL.ImageShow.EogViewer
|
||||||
.. autoclass:: PIL.ImageShow.XVViewer
|
.. autoclass:: PIL.ImageShow.XVViewer
|
||||||
|
|
||||||
|
|
|
@ -83,6 +83,18 @@ instances, so it will only be used by ``im.show()`` or :py:func:`.ImageShow.show
|
||||||
if none of the other viewers are available. This means that the behaviour of
|
if none of the other viewers are available. This means that the behaviour of
|
||||||
:py:class:`PIL.ImageShow` will stay the same for most Pillow users.
|
:py:class:`PIL.ImageShow` will stay the same for most Pillow users.
|
||||||
|
|
||||||
|
ImageShow.GmDisplayViewer
|
||||||
|
^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
If GraphicsMagick is present, this new :py:class:`PIL.ImageShow.Viewer` subclass will
|
||||||
|
be registered. It uses GraphicsMagick_, an ImageMagick_ fork, to display images.
|
||||||
|
|
||||||
|
The GraphicsMagick based viewer has a lower priority than its ImageMagick
|
||||||
|
counterpart. Thus, if both ImageMagick and GraphicsMagick are installed,
|
||||||
|
``im.show()`` and :py:func:`.ImageShow.show()` prefer the viewer based on
|
||||||
|
ImageMagick, i.e the behaviour stays the same for Pillow users having
|
||||||
|
ImageMagick installed.
|
||||||
|
|
||||||
Saving TIFF with ICC profile
|
Saving TIFF with ICC profile
|
||||||
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
^^^^^^^^^^^^^^^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
@ -143,3 +155,12 @@ PyQt6
|
||||||
|
|
||||||
Support has been added for PyQt6. If it is installed, it will be used instead of
|
Support has been added for PyQt6. If it is installed, it will be used instead of
|
||||||
PySide6, PyQt5 or PySide2.
|
PySide6, PyQt5 or PySide2.
|
||||||
|
|
||||||
|
GraphicsMagick
|
||||||
|
^^^^^^^^^^^^^^
|
||||||
|
|
||||||
|
The test suite can now be run on systems which have GraphicsMagick_ but not
|
||||||
|
ImageMagick_ installed. If both are installed, the tests prefer ImageMagick.
|
||||||
|
|
||||||
|
.. _GraphicsMagick: http://www.graphicsmagick.org/
|
||||||
|
.. _ImageMagick: https://imagemagick.org/
|
||||||
|
|
|
@ -194,6 +194,15 @@ class DisplayViewer(UnixViewer):
|
||||||
return command, executable
|
return command, executable
|
||||||
|
|
||||||
|
|
||||||
|
class GmDisplayViewer(UnixViewer):
|
||||||
|
"""The GraphicsMagick ``gm display`` command."""
|
||||||
|
|
||||||
|
def get_command_ex(self, file, **options):
|
||||||
|
executable = "gm"
|
||||||
|
command = "gm display"
|
||||||
|
return command, executable
|
||||||
|
|
||||||
|
|
||||||
class EogViewer(UnixViewer):
|
class EogViewer(UnixViewer):
|
||||||
"""The GNOME Image Viewer ``eog`` command."""
|
"""The GNOME Image Viewer ``eog`` command."""
|
||||||
|
|
||||||
|
@ -220,6 +229,8 @@ class XVViewer(UnixViewer):
|
||||||
if sys.platform not in ("win32", "darwin"): # unixoids
|
if sys.platform not in ("win32", "darwin"): # unixoids
|
||||||
if shutil.which("display"):
|
if shutil.which("display"):
|
||||||
register(DisplayViewer)
|
register(DisplayViewer)
|
||||||
|
if shutil.which("gm"):
|
||||||
|
register(GmDisplayViewer)
|
||||||
if shutil.which("eog"):
|
if shutil.which("eog"):
|
||||||
register(EogViewer)
|
register(EogViewer)
|
||||||
if shutil.which("xv"):
|
if shutil.which("xv"):
|
||||||
|
|
Loading…
Reference in New Issue
Block a user