summaryrefslogtreecommitdiff
diff options
context:
space:
mode:
-rw-r--r--example/demo.rst12
-rw-r--r--presentty/image.py44
-rw-r--r--presentty/rst.py4
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
154.. image:: gg.jpg 154.. image:: gg.jpg
155 155
156"Golden Gate Bridge" by Kevin Cole (CC-BY: https://flic.kr/p/7L2Rdu) 156"Golden Gate Bridge" by Kevin Cole (CC-BY: https://flic.kr/p/7L2Rdu)
157
158Scaling Images
159==============
160.. container:: handout
161
162 You can also give the image directive a scale parameter to scale the image.
163 the image will be centered within the slide.
164
165.. image:: gg.jpg
166 :scale: 75
167
168"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):
32 return 'f' 32 return 'f'
33 33
34class ANSIImage(urwid.Widget): 34class ANSIImage(urwid.Widget):
35 def __init__(self, uri, hinter=None): 35 def __init__(self, uri, hinter=None, scale=1, background=None):
36 super(ANSIImage, self).__init__() 36 super(ANSIImage, self).__init__()
37 self.uri = uri 37 self.uri = uri
38 image = self._loadImage() 38 image = self._loadImage()
39 self.htmlparser = HTMLParser.HTMLParser() 39 self.htmlparser = HTMLParser.HTMLParser()
40 self.ratio = float(image.size[0])/float(image.size[1]) 40 self.ratio = float(image.size[0])/float(image.size[1])
41 self.hinter = hinter 41 self.hinter = hinter
42 if scale > 1:
43 scale = 1
44 self.scale = scale
45 self.background = background or 'black'
42 46
43 def _loadImage(self): 47 def _loadImage(self):
44 image = PIL.Image.open(self.uri) 48 image = PIL.Image.open(self.uri)
@@ -81,7 +85,18 @@ class ANSIImage(urwid.Widget):
81 def render(self, size, focus=False): 85 def render(self, size, focus=False):
82 spanre = self.SPAN_RE 86 spanre = self.SPAN_RE
83 htmlparser = self.htmlparser 87 htmlparser = self.htmlparser
84 width, height = self.pack(size, focus) 88
89 # Calculate image size and any bounding box
90 total_width, total_height = self.pack(size, focus)
91 width, height = self.pack([s * self.scale for s in size], focus)
92 width = int(width)
93 height = int(height)
94 top_pad = (total_height - height) // 2
95 bottom_pad = total_height - height - top_pad
96 left_pad = (total_width - width) // 2
97 right_pad = total_width - width - left_pad
98 padding_attr = urwid.AttrSpec(self.background, self.background)
99
85 jp2a = subprocess.Popen(['jp2a', '--colors', '--fill', 100 jp2a = subprocess.Popen(['jp2a', '--colors', '--fill',
86 '--width=%s' % width, 101 '--width=%s' % width,
87 '--height=%s' % height, 102 '--height=%s' % height,
@@ -104,10 +119,23 @@ class ANSIImage(urwid.Widget):
104 current_fg = None 119 current_fg = None
105 current_bg = None 120 current_bg = None
106 current_props = None 121 current_props = None
122
123 # Top pad
124 for padding in range(0, top_pad):
125 line_list.append(' ' * total_width)
126 attr_list.append([(padding_attr, 1)] * total_width)
127
107 for line in data.split('<br/>'): 128 for line in data.split('<br/>'):
108 if not line: 129 if not line:
109 continue 130 continue
131
132 # Left pad
133 line_text += ' ' * left_pad
134 for fake_attr in range(0, left_pad):
135 line_attrs.append((padding_attr, 1))
136
110 for span in line.split('</span>'): 137 for span in line.split('</span>'):
138
111 if not span: 139 if not span:
112 continue 140 continue
113 m = spanre.match(span) 141 m = spanre.match(span)
@@ -141,10 +169,22 @@ class ANSIImage(urwid.Widget):
141 current_attr = [None, 0] 169 current_attr = [None, 0]
142 current_fg = None 170 current_fg = None
143 current_bg = None 171 current_bg = None
172
173 # Right pad
174 line_text += ' ' * right_pad
175 for fake_attr in range(0, right_pad):
176 line_attrs.append((padding_attr, 1))
177
144 line_list.append(line_text) 178 line_list.append(line_text)
145 line_text = '' 179 line_text = ''
146 attr_list.append(line_attrs) 180 attr_list.append(line_attrs)
147 line_attrs = [] 181 line_attrs = []
182
183 # Bottom pad
184 for padding in range(0, bottom_pad):
185 line_list.append(' ' * total_width)
186 attr_list.append([(padding_attr, 1)] * total_width)
187
148 canvas = urwid.TextCanvas(line_list, attr_list) 188 canvas = urwid.TextCanvas(line_list, attr_list)
149 return canvas 189 return canvas
150 190
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):
306 if not PIL: 306 if not PIL:
307 return 307 return
308 uri = node['uri'] 308 uri = node['uri']
309 scale = float(node.get('scale', 100))/100.0
309 fn = os.path.join(self.basedir, uri) 310 fn = os.path.join(self.basedir, uri)
310 w = image.ANSIImage(fn, self.hinter) 311 w = image.ANSIImage(fn, self.hinter, scale=scale,
312 background=self.palette['_default'].background)
311 self._append(node, w, 'pack') 313 self._append(node, w, 'pack')
312 314
313 def visit_ansi(self, node): 315 def visit_ansi(self, node):