Skip to content

Commit 9f54d50

Browse files
committed
Move optional resizing into own function
1 parent c4b75ee commit 9f54d50

File tree

1 file changed

+45
-28
lines changed

1 file changed

+45
-28
lines changed

src/jupyter_contrib_nbextensions/nbconvert_support/pre_embedimages.py

Lines changed: 45 additions & 28 deletions
Original file line numberDiff line numberDiff line change
@@ -33,13 +33,14 @@ class EmbedImagesPreprocessor(Preprocessor):
3333
3434
$ jupyter nbconvert --to html --EmbedImagesPreprocessor.embed_images=True mynotebook.ipynb
3535
36-
Further options are
36+
Further options are::
3737
3838
EmbedImagesPreprocessor.embed_remote_images=True
3939
4040
to additionally embeds all images referenced by an url
4141
(e.g. http://jupyter.org/assets/nav_logo.svg) instead of a local file name.
42-
Also
42+
43+
Another configuration option is::
4344
4445
EmbedImagesPreprocessor.resize=small
4546
@@ -48,7 +49,8 @@ class EmbedImagesPreprocessor(Preprocessor):
4849
version. Works only for raster images (i.e. png, jpg).
4950
Valid resize settings are: small = 500px, mid = 1000px, large = 2000px
5051
for maximum size in length or width. No upscaling of small images will
51-
be performed.
52+
be performed. The Python package `PIL` needs to be installed for this
53+
option to work.
5254
5355
Example::
5456
@@ -62,13 +64,49 @@ class EmbedImagesPreprocessor(Preprocessor):
6264
embed_images = Bool(False, help="Embed images as attachment").tag(config=True)
6365
embed_remote_images = Bool(False, help="Embed images referenced by an url as attachment").tag(config=True)
6466
resize = Unicode('', help="Resize images to save space (reduce size)").tag(config=True)
67+
imgsizes = {'small': 500, 'mid': 1000, 'large': 2000}
6568

6669
def preprocess(self, nb, resources):
6770
"""Skip preprocessor if not enabled"""
6871
if self.embed_images:
6972
nb, resources = super(EmbedImagesPreprocessor, self).preprocess(nb, resources)
7073
return nb, resources
7174

75+
def resize_image(self, imgname, imgformat, imgdata):
76+
"""Resize images if desired and PIL is installed
77+
78+
Parameters
79+
----------
80+
imgname: str
81+
Name of image
82+
imgformat: str
83+
Format of image (JPG or PNG)
84+
imgdata:
85+
Binary image data
86+
87+
"""
88+
if imgformat in ['png', 'jpg']:
89+
from io import BytesIO
90+
try:
91+
from PIL import Image
92+
except ImportError:
93+
self.log.info("Pillow library not available to resize images")
94+
return imgdata
95+
# Only make images smaller when rescaling
96+
im = Image.open(BytesIO(imgdata))
97+
factor = self.imgsizes[self.resize] / max(im.size)
98+
if factor < 1.0:
99+
newsize = (int(im.size[0] * factor), int(im.size[1] * factor))
100+
newim = im.resize(newsize)
101+
fp = BytesIO()
102+
# PIL requires JPEG instead of JPG
103+
newim.save(fp, format=imgformat.replace('jpg', 'jpeg'))
104+
imgdata = fp.getvalue()
105+
fp.close()
106+
self.log.debug("Resized %d x %d image %s to size %d x %d pixels" %
107+
(im.size[0], im.size[1], imgname, newsize[0], newsize[1]))
108+
return imgdata
109+
72110
def replfunc_md(self, match):
73111
"""Read image and store as base64 encoded attachment"""
74112
url = match.group(2)
@@ -85,31 +123,10 @@ def replfunc_md(self, match):
85123
with open(filename, 'rb') as f:
86124
data = f.read()
87125

88-
# resize settings: small -> 500px, mid -> 1000px, large -> 200px
89-
imgsizes = {'small': 500, 'mid': 1000, 'large': 2000}
90-
if self.resize in imgsizes.keys() and imgformat in ['png', 'jpg']:
91-
from io import BytesIO
92-
try:
93-
from PIL import Image
94-
except ImportError:
95-
self.log.info("Pillow library not available to resize images")
96-
Image = None
97-
if Image:
98-
# Only make images smaller when rescaling
99-
im = Image.open(BytesIO(data))
100-
factor = imgsizes[self.resize] / max(im.size)
101-
if factor < 1.0:
102-
newsize = (int(im.size[0] * factor), int(im.size[1] * factor))
103-
newim = im.resize(newsize)
104-
fp = BytesIO()
105-
# PIL requires JPEG instead of JPG
106-
newim.save(fp, format=imgformat.replace('jpg', 'jpeg'))
107-
data = fp.getvalue()
108-
fp.close()
109-
self.log.debug("Resized %d x %d image %s to size %d x %d pixels" %
110-
(im.size[0], im.size[1], url, newsize[0], newsize[1]))
111-
112-
self.log.debug("embedding url: %s, format: %s" % (url, imgformat))
126+
if self.resize in self.imgsizes.keys():
127+
data = self.resize_image(url, imgformat, data)
128+
129+
self.log.debug("Embedding url: %s, format: %s" % (url, imgformat))
113130
b64_data = base64.b64encode(data).decode("utf-8")
114131
self.attachments[url] = {'image/' + imgformat: b64_data}
115132

0 commit comments

Comments
 (0)