Skip to content

Commit 63a3a08

Browse files
committed
Address issue 4225
We now cover an additional case of missing / not provided color space, as suggested in the issue description. We are also taking the opportunity to provide a method that directly creates a PIL Image.
1 parent 00f2309 commit 63a3a08

File tree

2 files changed

+42
-20
lines changed

2 files changed

+42
-20
lines changed

docs/pixmap.rst

Lines changed: 10 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -33,8 +33,9 @@ Have a look at the :ref:`FAQ` section to see some pixmap usage "at work".
3333
:meth:`Pixmap.invert_irect` invert the pixels of a given area
3434
:meth:`Pixmap.pdfocr_save` save the pixmap as an OCRed 1-page PDF
3535
:meth:`Pixmap.pdfocr_tobytes` save the pixmap as an OCRed 1-page PDF
36-
:meth:`Pixmap.pil_save` save as image using pillow
37-
:meth:`Pixmap.pil_tobytes` write to `bytes` object using pillow
36+
:meth:`Pixmap.pil_image` create a Pillow Image
37+
:meth:`Pixmap.pil_save` save as a Pillow Image
38+
:meth:`Pixmap.pil_tobytes` write to `bytes` as a Pillow Image
3839
:meth:`Pixmap.pixel` return the value of a pixel
3940
:meth:`Pixmap.save` save the pixmap in a variety of formats
4041
:meth:`Pixmap.set_alpha` set alpha values
@@ -388,9 +389,14 @@ Have a look at the :ref:`FAQ` section to see some pixmap usage "at work".
388389
doc.save("ocr-images.pdf")
389390

390391

391-
.. method:: pil_save(*args, unmultiply=False, **kwargs)
392+
.. method:: pil_image()
392393

393-
* New in v1.17.3
394+
Create a Pillow Image from the pixmap. PIL / Pillow must be installed.
395+
396+
:raises ImportError: if Pillow is not installed.
397+
:returns: a ˇˇPIL.Imageˇˇ object
398+
399+
.. method:: pil_save(*args, unmultiply=False, **kwargs)
394400

395401
Write the pixmap as an image file using Pillow. Use this method for output unsupported by MuPDF. Examples are
396402

src/__init__.py

Lines changed: 32 additions & 16 deletions
Original file line numberDiff line numberDiff line change
@@ -10097,7 +10097,10 @@ def color_topusage(self, clip=None):
1009710097
@property
1009810098
def colorspace(self):
1009910099
"""Pixmap Colorspace."""
10100-
return Colorspace(mupdf.fz_pixmap_colorspace(self.this))
10100+
cs = Colorspace(mupdf.fz_pixmap_colorspace(self.this))
10101+
if cs.name == "None":
10102+
return None
10103+
return cs
1010110104

1010210105
def copy(self, src, bbox):
1010310106
"""Copy bbox from another Pixmap."""
@@ -10227,44 +10230,57 @@ def pdfocr_tobytes(self, compress=True, language="eng", tessdata=None):
1022710230
self.pdfocr_save(bio, compress=compress, language=language, tessdata=tessdata)
1022810231
return bio.getvalue()
1022910232

10230-
def pil_save(self, *args, **kwargs):
10231-
"""Write to image file using Pillow.
10232-
10233-
Args are passed to Pillow's Image.save method, see their documentation.
10234-
Use instead of save when other output formats are desired.
10235-
"""
10233+
def pil_image(self):
10234+
"""Create a Pillow Image from the Pixmap."""
1023610235
try:
1023710236
from PIL import Image
1023810237
except ImportError:
1023910238
message("PIL/Pillow not installed")
1024010239
raise
1024110240

1024210241
cspace = self.colorspace
10243-
if cspace is None:
10242+
if not cspace:
1024410243
mode = "L"
1024510244
elif cspace.n == 1:
10246-
mode = "L" if self.alpha == 0 else "LA"
10245+
mode = "L" if not self.alpha else "LA"
1024710246
elif cspace.n == 3:
10248-
mode = "RGB" if self.alpha == 0 else "RGBA"
10247+
mode = "RGB" if not self.alpha else "RGBA"
1024910248
else:
1025010249
mode = "CMYK"
1025110250

1025210251
img = Image.frombytes(mode, (self.width, self.height), self.samples)
10252+
return img
10253+
10254+
def pil_save(self, *args, **kwargs):
10255+
"""Write to image file using Pillow.
10256+
10257+
An intermediate PIL Image is created, and its "save" method is used
10258+
to store the image. See Pillow documentation to learn about the
10259+
meaning of possible positional and keyword parameters.
10260+
Use this when other output formats are desired.
10261+
"""
10262+
img = self.pil_image()
1025310263

1025410264
if "dpi" not in kwargs.keys():
1025510265
kwargs["dpi"] = (self.xres, self.yres)
1025610266

1025710267
img.save(*args, **kwargs)
1025810268

1025910269
def pil_tobytes(self, *args, **kwargs):
10260-
"""Convert to binary image stream using pillow.
10270+
"""Convert to an image in memory using Pillow.
1026110271

10262-
Args are passed to Pillow's Image.save method, see their documentation.
10263-
Use instead of 'tobytes' when other output formats are needed.
10272+
An intermediate PIL Image is created, and its "save" method is used
10273+
to store the image. See Pillow documentation to learn about the
10274+
meaning of possible positional or keyword parameters.
10275+
Use this when other output formats are desired.
1026410276
"""
10265-
from io import BytesIO
10266-
bytes_out = BytesIO()
10267-
self.pil_save(bytes_out, *args, **kwargs)
10277+
bytes_out = io.BytesIO()
10278+
img = self.pil_image()
10279+
10280+
if "dpi" not in kwargs.keys():
10281+
kwargs["dpi"] = (self.xres, self.yres)
10282+
10283+
img.save(bytes_out, *args, **kwargs)
1026810284
return bytes_out.getvalue()
1026910285

1027010286
def pixel(self, x, y):

0 commit comments

Comments
 (0)