def initialize_fbos(self): texsize = self.texsize size = (texsize, texsize) # pass 1, update position # both fbo have the associated texture as destination, and other fbo # texture as source. for fbo in (self.fbo_pos, self.fbo_pos2): fbo.shader.fs = FS_P1 #self._print_shader(fbo.shader.fs) other_fbo = self.fbo_pos2 if fbo is self.fbo_pos else self.fbo_pos other_vel_fbo = self.fbo_vel2 if fbo is self.fbo_pos else self.fbo_vel with fbo: ClearColor(0, 0, 0, 0) ClearBuffers() BindTexture(texture=other_vel_fbo.texture, index=1) Rectangle(size=size, texture=other_fbo.texture) # pass 2, reduce velocity for fbo in (self.fbo_vel, self.fbo_vel2): fbo.shader.fs = FS_P2 other_fbo = self.fbo_vel2 if fbo is self.fbo_vel else self.fbo_vel with fbo: ClearColor(0, 0, 0, 0) ClearBuffers() Rectangle(size=size, texture=other_fbo.texture)
def capture_image(self, filename): """ Capture only the visible part of the camera, without the black border. Similar to export_to_png but with adjusted coordinates. :param filename: path to the target file name :return True """ if self.parent is not None: canvas_parent_index = self.parent.canvas.indexof(self.canvas) if canvas_parent_index > -1: self.parent.canvas.remove(self.canvas) nw, nh = self.norm_image_size fbo = Fbo(size=(nw, nh), with_stencilbuffer=True) with fbo: ClearColor(0, 0, 0, 0) ClearBuffers() Scale(1, -1, 1) x = -self.x-(self.width-nw)/2 y = -self.y-(self.height-nh)/2 - nh Translate(x, y, 0) fbo.add(self.canvas) fbo.draw() fbo.texture.save(filename, flipped=False) fbo.remove(self.canvas) if self.parent is not None and canvas_parent_index > -1: self.parent.canvas.insert(canvas_parent_index, self.canvas) return True
def export_as_image(self, *args, **kwargs): # overwrite the function, because ClearColor is set to black per default from kivy.core.image import Image scale = kwargs.get('scale', 1) if self.parent is not None: canvas_parent_index = self.parent.canvas.indexof(self.canvas) if canvas_parent_index > -1: self.parent.canvas.remove(self.canvas) fbo = Fbo(size=(self.width * scale, self.height * scale), with_stencilbuffer=True) with fbo: ClearColor(1, 1, 1, 1) ClearBuffers() Scale(1, -1, 1) Scale(scale, scale, 1) Translate(-self.x, -self.y - self.height, 0) fbo.add(self.canvas) fbo.draw() img = Image(fbo.texture) fbo.remove(self.canvas) if self.parent is not None and canvas_parent_index > -1: self.parent.canvas.insert(canvas_parent_index, self.canvas) return img
def capture_image(self, filename): if self.parent is not None: canvas_parent_index = self.parent.canvas.indexof(self.canvas) if canvas_parent_index > -1: self.parent.canvas.remove(self.canvas) nw, nh = self.norm_image_size fbo = Fbo(size=(nw, nh), with_stencilbuffer=True) with fbo: ClearColor(0, 0, 0, 0) ClearBuffers() Scale(1, -1, 1) x = -self.x - (self.width - nw) / 2 y = -self.y - (self.height - nh) / 2 - nh Translate(x, y, 0) fbo.add(self.canvas) fbo.draw() fbo.texture.save(filename, flipped=False) fbo.remove(self.canvas) if self.parent is not None and canvas_parent_index > -1: self.parent.canvas.insert(canvas_parent_index, self.canvas) return True
def __init__(self, **kwargs): # Make sure opengl context exists EventLoop.ensure_window() self.canvas = RenderContext(use_parent_projection=True, use_parent_modelview=True) with self.canvas: self.fbo = Fbo(size=self.size) with self.fbo.before: PushMatrix() with self.fbo: ClearColor(0, 0, 0, 0) ClearBuffers() self._background_color = Color(*self.background_color) self.fbo_rectangle = Rectangle(size=self.size) with self.fbo.after: PopMatrix() super(EffectWidget, self).__init__(**kwargs) Clock.schedule_interval(self._update_glsl, 0) fbind = self.fbind fbo_setup = self.refresh_fbo_setup fbind('size', fbo_setup) fbind('effects', fbo_setup) fbind('background_color', self._refresh_background_color) self.refresh_fbo_setup() self._refresh_background_color() # In case thi was changed in kwargs
def add_image(self, widget): filename = f"tmp_{self.img_counter}.png" output_size = (self.meta_data["width"], self.meta_data["height"]) if self.meta_data["WH_ratio"] != widget.width // widget.height: raise Exception("W/H ratio does not match") img_scale = self.meta_data["width"] / widget.width if widget.parent is not None: canvas_parent_index = widget.parent.canvas.indexof(widget.canvas) if canvas_parent_index > -1: widget.parent.canvas.remove(widget.canvas) fbo = Fbo(size=output_size, with_stencilbuffer=True) with fbo: ClearColor(0, 0, 0, 0) ClearBuffers() Scale(img_scale, -img_scale, img_scale) Translate(-widget.x, -widget.y - widget.height, 0) fbo.add(widget.canvas) fbo.draw() fbo.texture.save(self.tmp_imgs_path + filename, flipped=False) fbo.remove(widget.canvas) if widget.parent is not None and canvas_parent_index > -1: widget.parent.canvas.insert(canvas_parent_index, widget.canvas) self.img_counter += 1
def get_widget_pos_pixel(self, widget, positions): from kivy.graphics import Fbo, ClearColor, ClearBuffers canvas_parent_index = -2 if widget.parent is not None: canvas_parent_index = widget.parent.canvas.indexof(widget.canvas) if canvas_parent_index > -1: widget.parent.canvas.remove(widget.canvas) w, h = int(widget.width), int(widget.height) fbo = Fbo(size=(w, h), with_stencilbuffer=True) with fbo: ClearColor(0, 0, 0, 0) ClearBuffers() fbo.add(widget.canvas) fbo.draw() pixels = fbo.pixels fbo.remove(widget.canvas) if widget.parent is not None and canvas_parent_index > -1: widget.parent.canvas.insert(canvas_parent_index, widget.canvas) values = [] for x, y in positions: x = int(x) y = int(y) i = y * w * 4 + x * 4 values.append(tuple(pixels[i:i + 4])) return values
def get_frame_data(self, *args): """Return the content of this display as buffer. @see: widget.export_to_png """ del args if self._slide_manager_parent.parent is not None: canvas_parent_index = self._slide_manager_parent.parent.canvas.indexof(self._slide_manager_parent.canvas) if canvas_parent_index > -1: self._slide_manager_parent.parent.canvas.remove(self._slide_manager_parent.canvas) fbo = Fbo(size=self._slide_manager_parent.size, with_stencilbuffer=True) with fbo: ClearColor(0, 0, 0, 1) ClearBuffers() Scale(1, -1, 1) Translate(-self._slide_manager_parent.x, -self._slide_manager_parent.y - self._slide_manager_parent.height, 0) fbo.add(self._slide_manager_parent.canvas) fbo.draw() data = fbo.texture.pixels fbo.remove(self._slide_manager_parent.canvas) if self._slide_manager_parent.parent is not None and canvas_parent_index > -1: self._slide_manager_parent.parent.canvas.insert(canvas_parent_index, self._slide_manager_parent.canvas) return data
def get_root_pixels(self): """Returns all the pixels values of the widget containing the shapes, as well as the size of that widget. This is how you can save an image of whatever is currently displayed on screen. """ widget = self.root.ids.display_canvas canvas_parent_index = widget.parent.canvas.indexof(widget.canvas) if canvas_parent_index > -1: widget.parent.canvas.remove(widget.canvas) fbo = Fbo(size=widget.size, with_stencilbuffer=True) with fbo: ClearColor(0, 0, 0, 1) ClearBuffers() Scale(1, -1, 1) Translate(0, -widget.height, 0) fbo.add(widget.canvas) fbo.draw() pixels = fbo.pixels fbo.remove(widget.canvas) if canvas_parent_index > -1: widget.parent.canvas.insert(canvas_parent_index, widget.canvas) return pixels, widget.size
def make_screen_fbo(self, screen): fbo = Fbo(size=screen.size) with fbo: ClearColor(0, 0, 0, 1) ClearBuffers() fbo.add(screen.canvas) return fbo
def export_as_image(self, *args, **kwargs): '''Return an core :class:`~kivy.core.image.Image` of the actual widget. .. versionadded:: 1.11.0 ''' from kivy.core.image import Image scale = kwargs.get('scale', 1) if self.parent is not None: canvas_parent_index = self.parent.canvas.indexof(self.canvas) if canvas_parent_index > -1: self.parent.canvas.remove(self.canvas) fbo = Fbo(size=(self.width * scale, self.height * scale), with_stencilbuffer=True) with fbo: ClearColor(0, 0, 0, 0) ClearBuffers() Scale(1, -1, 1) Scale(scale, scale, 1) Translate(-self.x, -self.y - self.height, 0) fbo.add(self.canvas) fbo.draw() img = Image(fbo.texture) fbo.remove(self.canvas) if self.parent is not None and canvas_parent_index > -1: self.parent.canvas.insert(canvas_parent_index, self.canvas) return img
def bitmap(self): # self.export_to_png('test.png') # remove cross self.canvas.after.clear() image_scale = 36 / self.width fbo = Fbo(size=(36, 27), with_stencilbuffer=True) with fbo: ClearColor(0, 0, 0, 0) ClearBuffers() Scale(image_scale, -image_scale, image_scale) Translate(-self.x, -self.y - self.height, 0) fbo.add(self.canvas) fbo.draw() # fbo.texture.save('test_small.png', flipped=False) bm = np.fromstring(fbo.pixels, dtype=np.uint8).reshape(fbo.size[1], fbo.size[0], 4) fbo.remove(self.canvas) # return cross self.add_cross() return np.int64(np.all(bm[:, :, :3] == 0, axis=2))
def export_to_png(self, filename, *args): '''Saves an image of the widget and its children in png format at the specified filename. Works by removing the widget canvas from its parent, rendering to an :class:`~kivy.graphics.fbo.Fbo`, and calling :meth:`~kivy.graphics.texture.Texture.save`. ''' if self.parent is not None: canvas_parent_index = self.parent.canvas.indexof(self.canvas) self.parent.canvas.remove(self.canvas) fbo = Fbo(size=self.size) with fbo: ClearColor(0, 0, 0, 1) ClearBuffers() Translate(-self.x, -self.y, 0) fbo.add(self.canvas) fbo.draw() fbo.texture.save(filename) fbo.remove(self.canvas) if self.parent is not None: self.parent.canvas.insert(canvas_parent_index, self.canvas) return True
def _get_fbo(self,widget): '''get frame buffer object of widget. Args: widget: subclass of kivy.uix.widget. Returns: kivy.graphics.fbo ''' if widget.parent is not None: canvas_parent_index = widget.parent.canvas.indexof(self.canvas) if canvas_parent_index > -1: widget.parent.canvas.remove(widget.canvas) fbo = Fbo(size=widget.size, with_stencilbuffer=True) with fbo: PushMatrix() ClearColor(0, 0, 0, 0) ClearBuffers() Scale(1, -1, 1) Translate(-widget.x, -widget.y - widget.height, 0) Rotate(origin=widget.center, axis=(widget.center_x,0,0), angle=-180) return fbo
def __init__(self, **kwargs): # Make sure opengl context exists EventLoop.ensure_window() self.canvas = RenderContext(use_parent_projection=True, use_parent_modelview=True) with self.canvas: self.fbo = Fbo(size=self.size) with self.fbo.before: PushMatrix() self.fbo_translation = Translate(-self.x, -self.y, 0) with self.fbo: ClearColor(1, 1, 1, 1) Color(*self.background_color) ClearBuffers() self.fbo_rectangle = Rectangle(size=self.size) with self.fbo.after: PopMatrix() super(EffectWidget, self).__init__(**kwargs) Clock.schedule_interval(self._update_glsl, 0) self.bind(pos=self._update_translation, size=self.refresh_fbo_setup, effects=self.refresh_fbo_setup) self.refresh_fbo_setup()
def export_to_png(self, filename, *args, **kwargs): '''Saves an image of the widget and its children in png format at the specified filename. Works by removing the widget canvas from its parent, rendering to an :class:`~kivy.graphics.fbo.Fbo`, and calling :meth:`~kivy.graphics.texture.Texture.save`. .. note:: The image includes only this widget and its children. If you want to include widgets elsewhere in the tree, you must call :meth:`~Widget.export_to_png` from their common parent, or use :meth:`~kivy.core.window.WindowBase.screenshot` to capture the whole window. .. note:: The image will be saved in png format, you should include the extension in your filename. .. versionadded:: 1.9.0 :Parameters: `filename`: str The filename with which to save the png. `scale`: float The amount by which to scale the saved image, defaults to 1. .. versionadded:: 1.11.0 ''' scale = kwargs.get('scale', 1) if self.parent is not None: canvas_parent_index = self.parent.canvas.indexof(self.canvas) if canvas_parent_index > -1: self.parent.canvas.remove(self.canvas) fbo = Fbo(size=(self.width * scale, self.height * scale), with_stencilbuffer=True) with fbo: ClearColor(0, 0, 0, 0) ClearBuffers() Scale(1, -1, 1) Scale(scale, scale, 1) Translate(-self.x, -self.y - self.height, 0) fbo.add(self.canvas) fbo.draw() fbo.texture.save(filename, flipped=False) fbo.remove(self.canvas) if self.parent is not None and canvas_parent_index > -1: self.parent.canvas.insert(canvas_parent_index, self.canvas) return True
def refresh_fbo_setup(self, *args): '''(internal) Creates and assigns one :class:`~kivy.graphics.Fbo` per effect, and makes sure all sizes etc. are correct and consistent. ''' if self.width <= 0 or self.height <= 0: return # Add/remove fbos until there is one per effect while len(self.fbo_list) < len(self.effects): with self.canvas: new_fbo = EffectFbo(size=self.size) with new_fbo: ClearColor(0, 0, 0, 0) ClearBuffers() Color(1, 1, 1, 1) new_fbo.texture_rectangle = Rectangle(size=self.size) new_fbo.texture_rectangle.size = self.size self.fbo_list.append(new_fbo) while len(self.fbo_list) > len(self.effects): old_fbo = self.fbo_list.pop() self.canvas.remove(old_fbo) # Remove fbos from unused effects for effect in self._bound_effects: if effect not in self.effects: effect.fbo = None self._bound_effects = self.effects # Do resizing etc. self.fbo.size = self.size self.fbo_rectangle.size = self.size for i in range(len(self.fbo_list)): self.fbo_list[i].size = self.size self.fbo_list[i].texture_rectangle.size = self.size # If there are no effects, just draw our main fbo if len(self.fbo_list) == 0: self.texture = self.fbo.texture return for i in range(1, len(self.fbo_list)): fbo = self.fbo_list[i] fbo.texture_rectangle.texture = self.fbo_list[i - 1].texture # Build effect shaders for effect, fbo in zip(self.effects, self.fbo_list): effect.fbo = fbo self.fbo_list[0].texture_rectangle.texture = self.fbo.texture self.texture = self.fbo_list[-1].texture for fbo in self.fbo_list: fbo.draw() self.fbo.draw()
def test_fbo_pixels(self): from kivy.graphics import Fbo, ClearColor, ClearBuffers, Ellipse fbo = Fbo(size=(512, 512)) with fbo: ClearColor(0, 0, 0, 1) ClearBuffers() Ellipse(pos=(100, 100), size=(100, 100)) fbo.draw() data = fbo.pixels fbo.texture.save('results.png')
def make_screen_fbo(self, screen): fbo = Fbo(size=screen.size, with_stencilbuffer=True) with fbo: ClearColor(*self.clearcolor) ClearBuffers() fbo.add(screen.canvas) with fbo.before: PushMatrix() Translate(-screen.x, -screen.y, 0) with fbo.after: PopMatrix() return fbo
def make_screen_fbo(self, screen): fbo = Fbo(size=screen.size) with fbo: ClearColor(0, 0, 0, 1) ClearBuffers() fbo.add(screen.canvas) with fbo.before: PushMatrix() Translate(-screen.x, -screen.y, 0) with fbo.after: PopMatrix() return fbo
def __init__(self, **kwargs): self.canvas = Canvas() with self.canvas: self.fbo = Fbo(size=self.size) self.fbo_color = Color(1, 1, 1, 1) self.fbo_rect = Rectangle() with self.fbo: ClearColor(0, 0, 0, 0) ClearBuffers() # wait that all the instructions are in the canvas to set texture self.texture = self.fbo.texture super(FboFloatLayout, self).__init__(**kwargs)
def test_fbo_pixels(self): from kivy.graphics import Fbo, ClearColor, ClearBuffers, Ellipse fbo = Fbo(size=(512, 512)) with fbo: ClearColor(0, 0, 0, 1) ClearBuffers() Ellipse(pos=(100, 100), size=(100, 100)) fbo.draw() data = fbo.pixels import pygame surface = pygame.image.fromstring(data, (512, 512), 'RGBA', True) pygame.image.save(surface, "results.png")
def __init__(self, **kwargs): self.mesh_data = MeshData() self.canvas = Canvas() with self.canvas: self.fbo = Fbo(size=(10, 10), compute_normal_mat=True) self.fbo.add_reload_observer(self.populate_fbo) with self.fbo: ClearColor(0, 0, 0, 0) ClearBuffers() self.populate_fbo(self.fbo) super(GLWindow, self).__init__(**kwargs) Clock.schedule_interval(self.update_glsl, 1 / 60.)
def export(self, wid, *largs): fbo = Fbo(size=wid.size, with_stencilbuffer=True) with fbo: ClearColor(1, 1, 1, 1) ClearBuffers() #Scale(1, -1, 1) #Translate(-self.x, -self.y - self.height, 0) fbo.add(wid.canvas) fbo.draw() img = fbo.texture img.save('test.png') fbo.remove(wid.canvas)
def export_scaled_png(self): re_size = (720, 480) image_scale = 720/self.width fbo = Fbo(size=re_size, with_stencilbuffer=True) with fbo: ClearColor(0, 0, 0, 0) ClearBuffers() Scale(image_scale, -image_scale, image_scale) Translate(-self.x, -self.y - self.height, 0) fbo.add(self.canvas) fbo.draw() fbo.texture.save('images/complete/%s_mask.jpg'%self.img_name[:-4], flipped=False) fbo.remove(self.canvas)
def export_to_png(self, filename, *args): if self.parent is not None: canvas_parent_index = self.parent.canvas.indexof(self.canvas) self.parent.canvas.remove(self.canvas) fbo = Fbo(size=self.size, with_stencilbuffer=True) with fbo: ClearColor(0, 0, 0, 1) ClearBuffers() Scale(1, -1, 1) Translate(-self.x, -self.y - self.height, 0) fbo.add(self.canvas) fbo.draw() fbo.texture.save(filename, flipped=False) fbo.remove(self.canvas) if self.parent is not None: self.parent.canvas.insert(canvas_parent_index, self.canvas) return True
def export_to_png(self, filename, *args): '''Saves an image of the widget and its children in png format at the specified filename. Works by removing the widget canvas from its parent, rendering to an :class:`~kivy.graphics.fbo.Fbo`, and calling :meth:`~kivy.graphics.texture.Texture.save`. .. note:: The image includes only this widget and its children. If you want to include widgets elsewhere in the tree, you must call :meth:`~Widget.export_to_png` from their common parent, or use :meth:`~kivy.core.window.Window.screenshot` to capture the whole window. .. note:: The image will be saved in png format, you should include the extension in your filename. .. versionadded:: 1.8.1 ''' if self.parent is not None: canvas_parent_index = self.parent.canvas.indexof(self.canvas) self.parent.canvas.remove(self.canvas) fbo = Fbo(size=self.size) with fbo: ClearColor(0, 0, 0, 1) ClearBuffers() Translate(-self.x, -self.y, 0) fbo.add(self.canvas) fbo.draw() fbo.texture.save(filename) fbo.remove(self.canvas) if self.parent is not None: self.parent.canvas.insert(canvas_parent_index, self.canvas) return True
def __init__(self, **kwargs): self.lock = Lock() self.gl_depth = -3 self.mesh_data = MeshData() self.mesh_data.vertices = np.array([0, 0, 0, 0, 0, 0, 0, 0]) self.mesh_data.indices = np.array([0]) self.points = None self.canvas = Canvas() with self.canvas: self.fbo = Fbo(size=(10, 10), compute_normal_mat=True) self.fbo.add_reload_observer(self.populate_fbo) with self.fbo: ClearColor(1, 1, 1, 1) ClearBuffers() self.populate_fbo(self.fbo) super(ObjectRenderer, self).__init__(**kwargs) Clock.schedule_interval(self.update_glsl, 1 / 10.)
def screenshot(widget, filename='output.png', region=None): if widget.parent is not None: canvas_parent_index = widget.parent.canvas.indexof(widget.canvas) widget.parent.canvas.remove(widget.canvas) fbo = Fbo(size=widget.size) with fbo: ClearColor(0, 0, 0, 0) ClearBuffers() Translate(-widget.x, -widget.y, 0) fbo.add(widget.canvas) fbo.draw() fbo.texture.save(filename) fbo.remove(widget.canvas) if widget.parent is not None: widget.parent.canvas.insert(canvas_parent_index, widget.canvas) return True
def __init__(self, **kwargs): self.canvas = Canvas() with self.canvas: self.fbo = Fbo( size=self.size, with_depthbuffer=True, ) self.fbo_color = Color(1, 1, 1, 1) self.viewport = Rectangle( pos=self.pos, size=self.size, ) with self.fbo: ClearColor(0, 0, 0, 0) ClearBuffers() self.texture = self.fbo.texture super(TransparentLayout, self).__init__(**kwargs)