| 23 | |
| 24 | |
| 25 | class PILImageViewverWidget(gui.Image): |
| 26 | def __init__(self, filename=None, **kwargs): |
| 27 | self.app_instance = None |
| 28 | super(PILImageViewverWidget, self).__init__("/res:logo.png", **kwargs) |
| 29 | self.frame_index = 0 |
| 30 | self._buf = None |
| 31 | if filename: |
| 32 | self.load(filename) |
| 33 | |
| 34 | def load(self, file_path_name): |
| 35 | pil_image = PIL.Image.open(file_path_name) |
| 36 | self._buf = io.BytesIO() |
| 37 | pil_image.save(self._buf, format='png') |
| 38 | |
| 39 | self.refresh() |
| 40 | |
| 41 | def search_app_instance(self, node): |
| 42 | if issubclass(node.__class__, remi.server.App): |
| 43 | return node |
| 44 | if not hasattr(node, "get_parent"): |
| 45 | return None |
| 46 | return self.search_app_instance(node.get_parent()) |
| 47 | |
| 48 | def refresh(self, *args): |
| 49 | if self.app_instance==None: |
| 50 | self.app_instance = self.search_app_instance(self) |
| 51 | if self.app_instance==None: |
| 52 | return |
| 53 | self.frame_index = self.frame_index + 1 |
| 54 | self.app_instance.execute_javascript(""" |
| 55 | url = '/%(id)s/get_image_data?index=%(frame_index)s'; |
| 56 | |
| 57 | xhr = null; |
| 58 | xhr = new XMLHttpRequest(); |
| 59 | xhr.open('GET', url, true); |
| 60 | xhr.responseType = 'blob' |
| 61 | xhr.onload = function(e){ |
| 62 | urlCreator = window.URL || window.webkitURL; |
| 63 | urlCreator.revokeObjectURL(document.getElementById('%(id)s').src); |
| 64 | imageUrl = urlCreator.createObjectURL(this.response); |
| 65 | document.getElementById('%(id)s').src = imageUrl; |
| 66 | } |
| 67 | xhr.send(); |
| 68 | """ % {'id': id(self), 'frame_index':self.frame_index}) |
| 69 | |
| 70 | def get_image_data(self, index=0): |
| 71 | try: |
| 72 | self._buf.seek(0) |
| 73 | headers = {'Content-type': 'image/png'} |
| 74 | return [self._buf.read(), headers] |
| 75 | except: |
| 76 | print(traceback.format_exc()) |
| 77 | return None, None |
| 78 | |
| 79 | |
| 80 | class MyApp(App): |