Skip to content

Commit 0ac415f

Browse files
committed
Simplify pdf image output.
- Inline _unpack into its only caller writeImages. - Let _writeImg infer the image size and grayscaleness from the data shape.
1 parent 9a1873f commit 0ac415f

File tree

1 file changed

+35
-41
lines changed

1 file changed

+35
-41
lines changed

lib/matplotlib/backends/backend_pdf.py

+35-41
Original file line numberDiff line numberDiff line change
@@ -1410,30 +1410,6 @@ def imageObject(self, image):
14101410
self._images[id(image)] = (image, name, ob)
14111411
return name
14121412

1413-
def _unpack(self, im):
1414-
"""
1415-
Unpack the image object im into height, width, data, alpha,
1416-
where data and alpha are HxWx3 (RGB) or HxWx1 (grayscale or alpha)
1417-
arrays, except alpha is None if the image is fully opaque.
1418-
"""
1419-
h, w = im.shape[:2]
1420-
im = im[::-1]
1421-
if im.ndim == 2:
1422-
return h, w, im, None
1423-
else:
1424-
rgb = im[:, :, :3]
1425-
rgb = np.array(rgb, order='C')
1426-
# PDF needs a separate alpha image
1427-
if im.shape[2] == 4:
1428-
alpha = im[:, :, 3][..., None]
1429-
if np.all(alpha == 255):
1430-
alpha = None
1431-
else:
1432-
alpha = np.array(alpha, order='C')
1433-
else:
1434-
alpha = None
1435-
return h, w, rgb, alpha
1436-
14371413
def _writePng(self, data):
14381414
"""
14391415
Write the image *data* into the pdf file using png
@@ -1455,26 +1431,26 @@ def _writePng(self, data):
14551431
buffer.seek(length, 1)
14561432
buffer.seek(4, 1) # skip CRC
14571433

1458-
def _writeImg(self, data, height, width, grayscale, id, smask=None):
1434+
def _writeImg(self, data, id, smask=None):
14591435
"""
1460-
Write the image *data* of size *height* x *width*, as grayscale
1461-
if *grayscale* is true and RGB otherwise, as pdf object *id*
1462-
and with the soft mask (alpha channel) *smask*, which should be
1463-
either None or a *height* x *width* x 1 array.
1436+
Write the image *data*, of shape ``(height, width, 1)`` (grayscale) or
1437+
``(height, width, 3)`` (RGB), as pdf object *id* and with the soft mask
1438+
(alpha channel) *smask*, which should be either None or a ``(height,
1439+
width, 1)`` array.
14641440
"""
1441+
height, width, colors = data.shape
14651442

1466-
obj = {'Type': Name('XObject'),
1467-
'Subtype': Name('Image'),
1468-
'Width': width,
1469-
'Height': height,
1470-
'ColorSpace': Name('DeviceGray' if grayscale
1471-
else 'DeviceRGB'),
1443+
obj = {'Type': Name('XObject'),
1444+
'Subtype': Name('Image'),
1445+
'Width': width,
1446+
'Height': height,
1447+
'ColorSpace': Name({1: 'DeviceGray', 3: 'DeviceRGB'}[colors]),
14721448
'BitsPerComponent': 8}
14731449
if smask:
14741450
obj['SMask'] = smask
14751451
if rcParams['pdf.compression']:
14761452
png = {'Predictor': 10,
1477-
'Colors': 1 if grayscale else 3,
1453+
'Colors': colors,
14781454
'Columns': width}
14791455
else:
14801456
png = None
@@ -1492,14 +1468,32 @@ def _writeImg(self, data, height, width, grayscale, id, smask=None):
14921468

14931469
def writeImages(self):
14941470
for img, name, ob in self._images.values():
1495-
height, width, data, adata = self._unpack(img)
1496-
if adata is not None:
1471+
img = img[::-1]
1472+
# Unpack image array *img* into ``(data, alpha)``, which have
1473+
# shape ``(height, width, 3)`` (RGB) or ``(height, width, 1)``
1474+
# (grayscale or alpha), except that alpha is None if the image is
1475+
# fully opaque.
1476+
if img.ndim == 2:
1477+
data = img[:, :, None]
1478+
alpha = None
1479+
else:
1480+
data = img[:, :, :3]
1481+
data = np.array(data, order='C')
1482+
# PDF needs a separate alpha image.
1483+
if img.shape[2] == 4:
1484+
alpha = img[:, :, 3][..., None]
1485+
if np.all(alpha == 255):
1486+
alpha = None
1487+
else:
1488+
alpha = np.array(alpha, order='C')
1489+
else:
1490+
alpha = None
1491+
if alpha is not None:
14971492
smaskObject = self.reserveObject("smask")
1498-
self._writeImg(adata, height, width, True, smaskObject.id)
1493+
self._writeImg(alpha, smaskObject.id)
14991494
else:
15001495
smaskObject = None
1501-
self._writeImg(data, height, width, False,
1502-
ob.id, smaskObject)
1496+
self._writeImg(data, ob.id, smask=smaskObject)
15031497

15041498
def markerObject(self, path, trans, fill, stroke, lw, joinstyle,
15051499
capstyle):

0 commit comments

Comments
 (0)