From 01d8f282a472da248d2a70cc2319797974a12501 Mon Sep 17 00:00:00 2001 From: Toshio Kuratomi Date: Mon, 17 Aug 2015 04:09:46 -0700 Subject: Allow scaling of images --- example/demo.rst | 12 ++++++++++++ presentty/image.py | 44 ++++++++++++++++++++++++++++++++++++++++++-- presentty/rst.py | 4 +++- 3 files changed, 57 insertions(+), 3 deletions(-) diff --git a/example/demo.rst b/example/demo.rst index c105e7d..e202bc2 100644 --- a/example/demo.rst +++ b/example/demo.rst @@ -154,3 +154,15 @@ Images .. image:: gg.jpg "Golden Gate Bridge" by Kevin Cole (CC-BY: https://flic.kr/p/7L2Rdu) + +Scaling Images +============== +.. container:: handout + + You can also give the image directive a scale parameter to scale the image. + the image will be centered within the slide. + +.. image:: gg.jpg + :scale: 75 + +"Golden Gate Bridge" by Kevin Cole (CC-BY: https://flic.kr/p/7L2Rdu) diff --git a/presentty/image.py b/presentty/image.py index 9aabee8..d82face 100644 --- a/presentty/image.py +++ b/presentty/image.py @@ -32,13 +32,17 @@ def nearest_color(x): return 'f' class ANSIImage(urwid.Widget): - def __init__(self, uri, hinter=None): + def __init__(self, uri, hinter=None, scale=1, background=None): super(ANSIImage, self).__init__() self.uri = uri image = self._loadImage() self.htmlparser = HTMLParser.HTMLParser() self.ratio = float(image.size[0])/float(image.size[1]) self.hinter = hinter + if scale > 1: + scale = 1 + self.scale = scale + self.background = background or 'black' def _loadImage(self): image = PIL.Image.open(self.uri) @@ -81,7 +85,18 @@ class ANSIImage(urwid.Widget): def render(self, size, focus=False): spanre = self.SPAN_RE htmlparser = self.htmlparser - width, height = self.pack(size, focus) + + # Calculate image size and any bounding box + total_width, total_height = self.pack(size, focus) + width, height = self.pack([s * self.scale for s in size], focus) + width = int(width) + height = int(height) + top_pad = (total_height - height) // 2 + bottom_pad = total_height - height - top_pad + left_pad = (total_width - width) // 2 + right_pad = total_width - width - left_pad + padding_attr = urwid.AttrSpec(self.background, self.background) + jp2a = subprocess.Popen(['jp2a', '--colors', '--fill', '--width=%s' % width, '--height=%s' % height, @@ -104,10 +119,23 @@ class ANSIImage(urwid.Widget): current_fg = None current_bg = None current_props = None + + # Top pad + for padding in range(0, top_pad): + line_list.append(' ' * total_width) + attr_list.append([(padding_attr, 1)] * total_width) + for line in data.split('
'): if not line: continue + + # Left pad + line_text += ' ' * left_pad + for fake_attr in range(0, left_pad): + line_attrs.append((padding_attr, 1)) + for span in line.split(''): + if not span: continue m = spanre.match(span) @@ -141,10 +169,22 @@ class ANSIImage(urwid.Widget): current_attr = [None, 0] current_fg = None current_bg = None + + # Right pad + line_text += ' ' * right_pad + for fake_attr in range(0, right_pad): + line_attrs.append((padding_attr, 1)) + line_list.append(line_text) line_text = '' attr_list.append(line_attrs) line_attrs = [] + + # Bottom pad + for padding in range(0, bottom_pad): + line_list.append(' ' * total_width) + attr_list.append([(padding_attr, 1)] * total_width) + canvas = urwid.TextCanvas(line_list, attr_list) return canvas diff --git a/presentty/rst.py b/presentty/rst.py index 8368a6a..3c55f1e 100644 --- a/presentty/rst.py +++ b/presentty/rst.py @@ -306,8 +306,10 @@ class UrwidTranslator(docutils.nodes.GenericNodeVisitor): if not PIL: return uri = node['uri'] + scale = float(node.get('scale', 100))/100.0 fn = os.path.join(self.basedir, uri) - w = image.ANSIImage(fn, self.hinter) + w = image.ANSIImage(fn, self.hinter, scale=scale, + background=self.palette['_default'].background) self._append(node, w, 'pack') def visit_ansi(self, node): -- cgit v1.2.3