diff options
| author | Toshio Kuratomi <toshio@fedoraproject.org> | 2015-08-17 04:09:46 -0700 |
|---|---|---|
| committer | James E. Blair <corvus@gnu.org> | 2016-11-20 10:39:56 -0800 |
| commit | 01d8f282a472da248d2a70cc2319797974a12501 (patch) | |
| tree | 8e535ec2bdd25271202d605226cd6c8ebbed9810 | |
| parent | de6deb817bd374e2d8ad44623348061fee20f280 (diff) | |
Allow scaling of images
| -rw-r--r-- | example/demo.rst | 12 | ||||
| -rw-r--r-- | presentty/image.py | 44 | ||||
| -rw-r--r-- | 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 | |||
| 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 | |||
| 158 | Scaling 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 | ||
| 34 | class ANSIImage(urwid.Widget): | 34 | class 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): |
