def update_viewport(self): from kivy.graphics.transformation import Matrix from math import radians w, h = self.system_size if self._density != 1: w, h = self.size w2, h2 = w / 2., h / 2. r = radians(self.rotation) # do projection matrix projection_mat = Matrix() projection_mat.view_clip(0.0, w, 0.0, h, -1.0, 1.0, 0) self.render_context['projection_mat'] = projection_mat # do modelview matrix modelview_mat = Matrix().translate(w2, h2, 0) modelview_mat = modelview_mat.multiply(Matrix().rotate(r, 0, 0, 1)) w, h = self.size w2, h2 = w / 2., h / 2. modelview_mat = modelview_mat.multiply(Matrix().translate(-w2, -h2, 0)) self.render_context['modelview_mat'] = modelview_mat frag_modelview_mat = Matrix() frag_modelview_mat.set(flat=modelview_mat.get()) self.render_context['frag_modelview_mat'] = frag_modelview_mat # redraw canvas self.canvas.ask_update() # and update childs self.update_childsize()
def render(self, node, matrix, color_transform): self._display.canvas.add(PushMatrix()) self._display.canvas.add(Color(*color_transform.c[:4])) matrix_instruction = MatrixInstruction() dmatrix = KivyMatrix() dmatrix.set(flat=[ matrix.scale_x, -matrix.skew_1, 0, 0, matrix.skew_0, -matrix.scale_y, 0, 0, 0, 0, 1, 0, matrix.translate_x, -matrix.translate_y, 0, 1 ]) matrix_instruction.matrix = dmatrix self._display.canvas.add(matrix_instruction) self._display.canvas.add(node) self._display.canvas.add(Color(1, 1, 1, 1)) self._display.canvas.add(PopMatrix())
def make_matrix(elems: List[List[float]]) -> Matrix: """Converts a matrix represented as a 2D list to a kivy Matrix. """ mat = Matrix() mat.set(array=elems) return mat
def _show_mea_outline(self, config, transform_matrix=None, color=(1, 215 / 255, 0, .2)): from kivy.graphics import (Line, StencilPush, StencilUse, StencilUnUse, StencilPop, Rectangle, Color) from kivy.graphics.context_instructions import (PushMatrix, PopMatrix, Rotate, Translate, Scale, MatrixInstruction, BindTexture) from kivy.graphics.transformation import Matrix from kivy.base import EventLoop EventLoop.ensure_window() from kivy.core.text import Label from kivy.metrics import dp, sp size = config['orig_size'] pos = config['pos'] canvas = config['canvas'] mea_w = max(self.view_controller.mea_num_cols - 1, 0) * \ self.view_controller.mea_pitch mea_h = max(self.view_controller.mea_num_rows - 1, 0) * \ self.view_controller.mea_pitch last_col = "ABCDEFGHJKLMNOPQRSTUVWXYZ"[ self.view_controller.mea_num_cols - 1] with canvas: StencilPush() Rectangle(pos=pos, size=size) StencilUse() PushMatrix() if transform_matrix is not None: mat = Matrix() mat.set(array=transform_matrix) m = MatrixInstruction() m.matrix = mat Color(*color) Line(points=[0, 0, mea_w, 0, mea_w, mea_h, 0, mea_h], close=True) label = Label(text='A1', font_size=sp(12)) label.refresh() _w, _h = label.texture.size rect = Rectangle(pos=(mea_w, mea_h - _h / 2.), size=label.texture.size) rect.texture = label.texture label = Label(text='A{}'.format(self.view_controller.mea_num_rows), font_size=sp(12)) label.refresh() _w, _h = label.texture.size rect = Rectangle(pos=(-_w, mea_h - _h / 2.), size=label.texture.size) rect.texture = label.texture label = Label(text='{}1'.format(last_col), font_size=sp(12)) label.refresh() _w, _h = label.texture.size rect = Rectangle(pos=(mea_w, -_h / 2.), size=label.texture.size) rect.texture = label.texture label = Label(text='{}{}'.format( last_col, self.view_controller.mea_num_rows), font_size=sp(12)) label.refresh() _w, _h = label.texture.size rect = Rectangle(pos=(-_w, -_h / 2.), size=label.texture.size) rect.texture = label.texture PopMatrix() StencilUnUse() Rectangle(pos=pos, size=size) StencilPop()
def _paint_electrodes_data_setup(self, config, electrode_names, spacing=2, draw_size=(0, 0), draw_size_hint=(1, 1), draw_pos=(0, 0), draw_pos_hint=(None, None), volt_scale=1e-6, time_axis_s=1, volt_axis=100, transform_matrix=None, label_width=70): from kivy.graphics import (Mesh, StencilPush, StencilUse, StencilUnUse, StencilPop, Rectangle, Color) from kivy.graphics.context_instructions import (PushMatrix, PopMatrix, Scale, MatrixInstruction) from kivy.graphics.transformation import Matrix from kivy.base import EventLoop EventLoop.ensure_window() from kivy.core.text import Label from kivy.metrics import dp, sp n_rows = len(electrode_names) if not n_rows: raise ValueError("There must be at least one electrode specified") n_cols = len(electrode_names[0]) if not n_cols: raise ValueError("There must be at least one electrode specified") if not all((len(row) == n_cols for row in electrode_names)): raise ValueError( "The number of electrodes in all rows must be the same") n_electrodes = sum(map(len, electrode_names)) orig_w, orig_h = config['orig_size'] fbo = config['canvas'] label_height = 45 if label_width else 0 draw_w, draw_h = draw_size draw_hint_w, draw_hint_h = draw_size_hint w = int(draw_w if draw_hint_w is None else orig_w * draw_hint_w) h = int(draw_h if draw_hint_h is None else orig_h * draw_hint_h) draw_x, draw_y = draw_pos draw_hint_x, draw_hint_y = draw_pos_hint x = int(draw_x if draw_hint_x is None else orig_w * draw_hint_x) y = int(draw_y if draw_hint_y is None else orig_h * draw_hint_y) ew = int((w - label_width - max(0, n_cols - 1) * spacing) / n_cols) eh = int((h - label_height - max(0, n_rows - 1) * spacing) / n_rows) with fbo: PushMatrix() # center = x + w / 2., y + h / 2. # if scale: # Scale(scale, scale, 1, origin=center) if transform_matrix is not None: mat = Matrix() mat.set(array=transform_matrix) m = MatrixInstruction() m.matrix = mat positions = [ (0, 0), ] * n_electrodes graphics = [ None, ] * n_electrodes i = 0 electrode_color = 1, 215 / 255, 0, 1 for row, row_names in enumerate(reversed(electrode_names)): ey = y + label_height if row: ey += (eh + spacing) * row for col, name in enumerate(row_names): if name is None: i += 1 continue ex = x + label_width if col: ex += (ew + spacing) * col positions[i] = ex, ey fbo.add(Color(*electrode_color)) fbo.add(StencilPush()) fbo.add(Rectangle(pos=(ex, ey), size=(ew, eh))) fbo.add(StencilUse()) graphics[i] = Mesh(mode='line_strip') fbo.add(graphics[i]) fbo.add(StencilUnUse()) fbo.add(Rectangle(pos=(ex, ey), size=(ew, eh))) fbo.add(StencilPop()) i += 1 if label_width: if not col: fbo.add(Color(1, 1, 1, 1)) label = Label(text=name, font_size=sp(40)) label.refresh() _w, _h = label.texture.size rect = Rectangle(pos=(x, ey + (eh - _h) / 2.), size=label.texture.size) rect.texture = label.texture fbo.add(rect) if not row: fbo.add(Color(1, 1, 1, 1)) label = Label(text=name, font_size=sp(40)) label.refresh() _w, _h = label.texture.size rect = Rectangle(pos=(ex + (ew - _w) / 2., y), size=label.texture.size) rect.texture = label.texture fbo.add(rect) with fbo: Color(1, 1, 1, 1) PopMatrix() electrodes_data = [ None, ] * n_electrodes # y_min, y_max = float('inf'), float('-inf') alignment = np.array(self.electrode_intensity_alignment) # get the frequency from any channel name = None for row_names in electrode_names: for name in row_names: if name is not None: break if name is not None: break freq = self.electrodes_metadata[name]['sampling_frequency'] frame_n = int(1 / config['rate'] * freq) n_t = int(time_axis_s * freq) t_vals = np.arange(n_t) / (n_t - 1) * ew y_scale = (eh / 2) / volt_axis for i, name in enumerate(itertools.chain(*electrode_names)): if name is None: continue offset, scale = self.get_electrode_offset_scale(name) electrodes_data[i] = \ self.electrodes_data[name], offset, scale / volt_scale # y_min = min(np.min(data), y_min) # y_max = max(np.max(data), y_max) new_config = { 'alignment': alignment, 'frame_n': frame_n, 't_vals': t_vals, 'y_scale': y_scale, 'electrodes_data': electrodes_data, 'n_t': n_t, 'positions': positions, 'graphics': graphics, 'eh': eh } return CallableGen(self._paint_electrodes_data(new_config))
def _show_image(config, img, scale=None, translation=None, rotation=None, transform_matrix=None): from kivy.graphics.texture import Texture from kivy.graphics.fbo import Fbo from kivy.graphics import (Mesh, StencilPush, StencilUse, StencilUnUse, StencilPop, Rectangle, Color) from kivy.graphics.context_instructions import (PushMatrix, PopMatrix, Rotate, Translate, Scale, MatrixInstruction, BindTexture) from kivy.graphics.transformation import Matrix img_fmt = img.get_pixel_format() img_w, img_h = img.get_size() size = config['orig_size'] pos = config['pos'] canvas = config['canvas'] if img_fmt not in ('yuv420p', 'rgba', 'rgb24', 'gray', 'bgr24', 'bgra'): ofmt = get_best_pix_fmt( img_fmt, ('yuv420p', 'rgba', 'rgb24', 'gray', 'bgr24', 'bgra')) swscale = SWScale(iw=img_w, ih=img_h, ifmt=img_fmt, ow=0, oh=0, ofmt=ofmt) img = swscale.scale(img) img_fmt = img.get_pixel_format() kivy_ofmt = { 'yuv420p': 'yuv420p', 'rgba': 'rgba', 'rgb24': 'rgb', 'gray': 'luminance', 'bgr24': 'bgr', 'bgra': 'bgra' }[img_fmt] if kivy_ofmt == 'yuv420p': w2 = int(img_w / 2) h2 = int(img_h / 2) tex_y = Texture.create(size=(img_w, img_h), colorfmt='luminance') tex_u = Texture.create(size=(w2, h2), colorfmt='luminance') tex_v = Texture.create(size=(w2, h2), colorfmt='luminance') with canvas: fbo = Fbo(size=(img_w, img_h)) with fbo: BindTexture(texture=tex_u, index=1) BindTexture(texture=tex_v, index=2) Rectangle(size=fbo.size, texture=tex_y) fbo.shader.fs = CeedDataReader._YUV_RGB_FS fbo['tex_y'] = 0 fbo['tex_u'] = 1 fbo['tex_v'] = 2 tex = fbo.texture dy, du, dv, _ = img.to_memoryview() tex_y.blit_buffer(dy, colorfmt='luminance') tex_u.blit_buffer(du, colorfmt='luminance') tex_v.blit_buffer(dv, colorfmt='luminance') else: tex = Texture.create(size=(img_w, img_h), colorfmt=kivy_ofmt) tex.blit_buffer(img.to_memoryview()[0], colorfmt=kivy_ofmt) tex.flip_vertical() with canvas: StencilPush() Rectangle(pos=pos, size=size) StencilUse() PushMatrix() center = pos[0] + size[0] / 2, pos[1] + size[1] / 2 if rotation: Rotate(angle=rotation, axis=(0, 0, 1), origin=center) if scale: Scale(scale, scale, 1, origin=center) if translation: Translate(*translation) if transform_matrix is not None: mat = Matrix() mat.set(array=transform_matrix) m = MatrixInstruction() m.matrix = mat Rectangle(size=(img_w, img_h), texture=tex, pos=pos) PopMatrix() StencilUnUse() Rectangle(pos=pos, size=size) StencilPop()
def recalc(self, *args, **kwargs): block = copy.deepcopy(self.block) block['x'] -= block['blend_left'] / 2 block['y'] -= block['blend_top'] / 2 block['width'] += block['blend_left'] / 2 + block['blend_right'] / 2 block['height'] += block['blend_top'] / 2 + block['blend_bottom'] / 2 print(block['x'], block['y'], block['width'], block['height']) if block['x'] < 0: block['x'] = 0 if block['y'] < 0: block['x'] = 0 if block['width'] > 1: block['width'] = 1 if block['height'] > 1: block['height'] = 1 w, h = self.source.texture.width, self.source.texture.height sw, sh = self.source.width / self.source.texture.width, self.source.height / self.source.texture.height # self.texture = self.source.texture.get_region( # sw * min(block['x'] * w, w) - (block['blend_left'] * w / 2), # sh * min(block['y'] * h, h) - (block['blend_top'] * h / 2), # sw * min(block['width'] * w, w) + (block['blend_right'] * w / 2), # sh * min(block['height'] * h, h) + (block['blend_bottom'] * h / 2) # ) self.texture = self.source.texture.get_region( sw * min(block['x'] * w, w), sh * min(block['y'] * h, h), sw * min(block['width'] * w, w), sh * min(block['height'] * h, h) ) before = [ [-1, -1], [1, -1], [1, 1], [-1, 1] ] # Adjust size of section if edge blending is used points = block['points'] points[3] = [points[3][0] - block['blend_left'], points[3][1] + block['blend_bottom']] points[2] = [points[2][0] + block['blend_right'], points[2][1] + block['blend_bottom']] points[0] = [points[0][0] - block['blend_left'], points[0][1] - block['blend_top']] points[1] = [points[1][0] + block['blend_right'], points[1][1] - block['blend_top']] after = numpy.array(points) A = [] for a, b in zip(after, before): A.append([ b[0], 0, -a[0] * b[0], b[1], 0, -a[0] * b[1], 1, 0]); A.append([ 0, b[0], -a[1] * b[0], 0, b[1], -a[1] * b[1], 0, 1]); A = numpy.array(A) B = numpy.array([[c for p in block['points'] for c in p]]) B = B.transpose() m = numpy.dot(numpy.linalg.inv(A), B) m = m.transpose().reshape(-1,).tolist() matrix = Matrix() matrix.set([ m[0], m[1], 0, m[2], m[3], m[4], 0, m[5], 0, 0, 1, 0, m[6], m[7], 0, 1 ]) self.canvas['uTransformMatrix'] = matrix self.canvas['brightness'] = float(block.get('brightness', 1)) self.canvas['alpha_mask'] = int(block.get('alpha_mask', False)) # Because Kivy can't pass booleans to shaders, apparently. self.canvas['adjust'] = float(self.client.minion['settings'].get('displayminion_color_adjust_range', 0)) self.canvas['tex_x'] = block['x'] self.canvas['tex_y'] = block['y'] self.canvas['tex_width'] = block['width'] self.canvas['tex_height'] = block['height'] self.canvas['blend_top'] = float(block['blend_top']) self.canvas['blend_bottom'] = float(block['blend_bottom']) self.canvas['blend_left'] = float(block['blend_left']) self.canvas['blend_right'] = float(block['blend_right']) self.canvas.clear() with self.canvas: self.rect = Rectangle(texture = self.texture, size = (2, 2), pos = (-1, -1))
class KivyRenderer: def __init__(self, lwf, bitmap, canvas): b = lwf.data.bitmaps[bitmap.objectId] if b.textureFragmentId == -1: return bx = FormatBitmapEx() bx.matrixId = b.matrixId bx.textureFragmentId = b.textureFragmentId bx.u = 0 bx.v = 0 bx.w = 1 bx.h = 1 f = lwf.data.textureFragments[b.textureFragmentId] t = lwf.data.textures[f.textureId] texturePath = t.filename filename = lwf.data.path + texturePath rect_coords, tex_coords = self.get_vertices(t, f, bx, False, False) # print(f"Looking for {filename}") texture = Image(filename).texture # self.m_mesh = Rectangle(pos=(rect_coords[0], rect_coords[1]), size=(rect_coords[2], rect_coords[3])) self.m_origin_transform = Translate( lwf.render_offset[0] * (lwf.scaleX / lwf.width), lwf.render_offset[1] * (lwf.scaleY / lwf.height)) self.m_mesh = Rectangle(pos=(rect_coords[0], rect_coords[1]), size=(rect_coords[2], rect_coords[3]), tex_coords=tex_coords, texture=texture) # self.m_mesh = Mesh(vertices=coordinates, indices=[1, 3, 2, 0, 1], mode='triangle_fan', texture=texture) self.m_color = Color(1, 1, 1, 1) self.m_matrix = Matrix() self.m_inst = MatrixInstruction() # self.m_mesh = Mesh(vertices=vertices, indices=[1, 3, 2, 0, 1], texture=texture, mode='triangle_fan') self.canvas = canvas def get_vertices(self, t, f, bx, flippedX, flippedY): tw = t.width th = t.height x = f.x y = f.y u = f.u v = f.v w = f.w h = f.h bu = bx.u * w bv = bx.v * h bw = bx.w bh = bx.h x += bu y += bv u += bu v += bv w *= bw h *= bh x0 = x / t.scale y0 = y / t.scale x1 = (x + w) / t.scale y1 = (y + h) / t.scale vertices = [x0, y0, x1 - x0, y1 - y0] if f.rotated == 0: u0 = u / tw v0 = v / th u1 = (u + w) / tw v1 = (v + h) / th if flippedX: tu1 = u1 u1 = u0 u0 = tu1 if flippedY: tv1 = v1 v1 = v0 v0 = tv1 # tex_coords = [u1, v1, u0, v1, u0, v0, u1, v0] tex_coords = [u0, v0, u1, v0, u1, v1, u0, v1] # coordinates = [x0, y0, u0, v0, x1, y0, u1, v0, x1, y1, u1, v1, x0, y1, u0, v1] # tex_coords = [u1, v1, u0, v1, u1, v0, u0, v0] # u1 v1 u0 v1 u1 v0 u0 v0 # blu blv bru brv tlu tlv tru trv # u0 v0 u1 v0 u0 v1 u1 v1 # tru trv tlu tlv bru brv blu blv # tex_coords = [u0, v0, u1, v0, u0, v1, u1, v1] else: u0 = u / tw v0 = v / th u1 = (u + h) / tw v1 = (v + w) / th tex_coords = [u0, v1, u0, v0, u1, v0, u1, v1] # coordinates = [x0, y0, u0, v1, x0, y1, u0, v0, x1, y1, u1, v0, x1, y1, u1, v0] # u0 v1 u0 v0 u1 v1 u1 v0 # blu blv bru brv tlu tlv tru trv # u1 v0 u1 v1 u0 v0 u0 v1 # tru trv tlu tlv bru brv blu blv # tex_coords = [u1, v0, u1, v1, u0, v0, u0, v1] return vertices, tex_coords def Destruct(self): pass def Update(self, matrix, colorTransform): print("Update") def Render(self, matrix, colorTransform, renderingIndex, renderingCount, visible): if not visible or colorTransform.multi.alpha == 0: return # print(matrix) # print("") self.m_color.rgba = (colorTransform.multi.red, colorTransform.multi.green, colorTransform.multi.blue, colorTransform.multi.alpha) self.m_matrix.set(flat=[ matrix.scaleX, -matrix.skew0, 0, 0, # matrix.skew0, -matrix.skew0 -matrix.skew1, matrix.scaleY, 0, 0, # matrix.scaleX, matrix.scaleY 0, 0, 1, 0, matrix.translateX, matrix.translateY, 0, 1 ]) # matrix.translateX, matrix.translateY self.m_inst.matrix = self.m_matrix self.canvas.add(PushMatrix()) self.canvas.add(Color(1, 0, 0, 1)) self.canvas.add(Translate(575, 300)) self.canvas.add(Ellipse(size=(5, 5))) self.canvas.add(self.m_origin_transform) self.canvas.add(Ellipse(size=(5, 5))) self.canvas.add(Scale(1, -1, 1, origin=(0, 0))) self.canvas.add(self.m_inst) self.canvas.add(self.m_color) self.canvas.add(self.m_mesh) self.canvas.add(PopMatrix()) self.canvas.ask_update()
def make_matrix(elems): mat = Matrix() mat.set(array=elems) return mat
def _show_mea_outline(self, config, transform_matrix=None): from kivy.graphics import ( Line, StencilPush, StencilUse, StencilUnUse, StencilPop, Rectangle, Color) from kivy.graphics.context_instructions import ( PushMatrix, PopMatrix, Rotate, Translate, Scale, MatrixInstruction, BindTexture) from kivy.graphics.transformation import Matrix from kivy.base import EventLoop EventLoop.ensure_window() from kivy.core.text import Label from kivy.metrics import dp, sp size = config['orig_size'] pos = config['pos'] canvas = config['canvas'] mea_w = max(self.view_controller.mea_num_cols - 1, 0) * \ self.view_controller.mea_pitch mea_h = max(self.view_controller.mea_num_rows - 1, 0) * \ self.view_controller.mea_pitch last_col = "ABCDEFGHJKLMNOPQRSTUVWXYZ"[ self.view_controller.mea_num_cols - 1] with canvas: StencilPush() Rectangle(pos=pos, size=size) StencilUse() PushMatrix() if transform_matrix is not None: mat = Matrix() mat.set(array=transform_matrix) m = MatrixInstruction() m.matrix = mat Color(1, 215 / 255, 0, .2) Line(points=[0, 0, mea_w, 0, mea_w, mea_h, 0, mea_h], close=True) label = Label(text='A1', font_size=sp(12)) label.refresh() _w, _h = label.texture.size rect = Rectangle( pos=(mea_w, mea_h - _h / 2.), size=label.texture.size) rect.texture = label.texture label = Label( text='A{}'.format(self.view_controller.mea_num_rows), font_size=sp(12)) label.refresh() _w, _h = label.texture.size rect = Rectangle( pos=(-_w, mea_h - _h / 2.), size=label.texture.size) rect.texture = label.texture label = Label(text='{}1'.format(last_col), font_size=sp(12)) label.refresh() _w, _h = label.texture.size rect = Rectangle(pos=(mea_w, -_h / 2.), size=label.texture.size) rect.texture = label.texture label = Label( text='{}{}'.format(last_col, self.view_controller.mea_num_rows), font_size=sp(12)) label.refresh() _w, _h = label.texture.size rect = Rectangle(pos=(-_w, -_h / 2.), size=label.texture.size) rect.texture = label.texture PopMatrix() StencilUnUse() Rectangle(pos=pos, size=size) StencilPop()
def _paint_electrodes_data_setup( self, config, electrode_names, spacing=2, draw_size=(0, 0), draw_size_hint=(1, 1), draw_pos=(0, 0), draw_pos_hint=(None, None), volt_scale=1e-6, time_axis_s=1, volt_axis=100, transform_matrix=None, label_width=70): from kivy.graphics import ( Mesh, StencilPush, StencilUse, StencilUnUse, StencilPop, Rectangle, Color) from kivy.graphics.context_instructions import ( PushMatrix, PopMatrix, Scale, MatrixInstruction) from kivy.graphics.transformation import Matrix from kivy.base import EventLoop EventLoop.ensure_window() from kivy.core.text import Label from kivy.metrics import dp, sp n_rows = len(electrode_names) if not n_rows: raise ValueError("There must be at least one electrode specified") n_cols = len(electrode_names[0]) if not n_cols: raise ValueError("There must be at least one electrode specified") if not all((len(row) == n_cols for row in electrode_names)): raise ValueError( "The number of electrodes in all rows must be the same") n_electrodes = sum(map(len, electrode_names)) orig_w, orig_h = config['orig_size'] fbo = config['canvas'] label_height = 45 if label_width else 0 draw_w, draw_h = draw_size draw_hint_w, draw_hint_h = draw_size_hint w = int(draw_w if draw_hint_w is None else orig_w * draw_hint_w) h = int(draw_h if draw_hint_h is None else orig_h * draw_hint_h) draw_x, draw_y = draw_pos draw_hint_x, draw_hint_y = draw_pos_hint x = int(draw_x if draw_hint_x is None else orig_w * draw_hint_x) y = int(draw_y if draw_hint_y is None else orig_h * draw_hint_y) ew = int((w - label_width - max(0, n_cols - 1) * spacing) / n_cols) eh = int((h - label_height - max(0, n_rows - 1) * spacing) / n_rows) with fbo: PushMatrix() # center = x + w / 2., y + h / 2. # if scale: # Scale(scale, scale, 1, origin=center) if transform_matrix is not None: mat = Matrix() mat.set(array=transform_matrix) m = MatrixInstruction() m.matrix = mat positions = [(0, 0), ] * n_electrodes graphics = [None, ] * n_electrodes i = 0 electrode_color = 1, 215 / 255, 0, 1 for row, row_names in enumerate(reversed(electrode_names)): ey = y + label_height if row: ey += (eh + spacing) * row for col, name in enumerate(row_names): if name is None: i += 1 continue ex = x + label_width if col: ex += (ew + spacing) * col positions[i] = ex, ey fbo.add(Color(*electrode_color)) fbo.add(StencilPush()) fbo.add(Rectangle(pos=(ex, ey), size=(ew, eh))) fbo.add(StencilUse()) graphics[i] = Mesh(mode='line_strip') fbo.add(graphics[i]) fbo.add(StencilUnUse()) fbo.add(Rectangle(pos=(ex, ey), size=(ew, eh))) fbo.add(StencilPop()) i += 1 if label_width: if not col: fbo.add(Color(1, 1, 1, 1)) label = Label(text=name, font_size=sp(40)) label.refresh() _w, _h = label.texture.size rect = Rectangle( pos=(x, ey + (eh - _h) / 2.), size=label.texture.size) rect.texture = label.texture fbo.add(rect) if not row: fbo.add(Color(1, 1, 1, 1)) label = Label(text=name, font_size=sp(40)) label.refresh() _w, _h = label.texture.size rect = Rectangle( pos=(ex + (ew - _w) / 2., y), size=label.texture.size) rect.texture = label.texture fbo.add(rect) with fbo: Color(1, 1, 1, 1) PopMatrix() electrodes_data = [None, ] * n_electrodes # y_min, y_max = float('inf'), float('-inf') alignment = np.array(self.electrode_intensity_alignment) # get the frequency from any channel name = None for row_names in electrode_names: for name in row_names: if name is not None: break if name is not None: break freq = self.electrodes_metadata[name]['sampling_frequency'] frame_n = int(1 / config['rate'] * freq) n_t = int(time_axis_s * freq) t_vals = np.arange(n_t) / (n_t - 1) * ew y_scale = (eh / 2) / volt_axis for i, name in enumerate(itertools.chain(*electrode_names)): if name is None: continue offset, scale = self.get_electrode_offset_scale(name) electrodes_data[i] = \ self.electrodes_data[name], offset, scale / volt_scale # y_min = min(np.min(data), y_min) # y_max = max(np.max(data), y_max) new_config = { 'alignment': alignment, 'frame_n': frame_n, 't_vals': t_vals, 'y_scale': y_scale, 'electrodes_data': electrodes_data, 'n_t': n_t, 'positions': positions, 'graphics': graphics, 'eh': eh} return CallableGen(self._paint_electrodes_data(new_config))
def _show_image( config, img, scale=None, translation=None, rotation=None, transform_matrix=None): from kivy.graphics.texture import Texture from kivy.graphics.fbo import Fbo from kivy.graphics import ( Mesh, StencilPush, StencilUse, StencilUnUse, StencilPop, Rectangle, Color) from kivy.graphics.context_instructions import ( PushMatrix, PopMatrix, Rotate, Translate, Scale, MatrixInstruction, BindTexture) from kivy.graphics.transformation import Matrix img_fmt = img.get_pixel_format() img_w, img_h = img.get_size() size = config['orig_size'] pos = config['pos'] canvas = config['canvas'] if img_fmt not in ('yuv420p', 'rgba', 'rgb24', 'gray', 'bgr24', 'bgra'): ofmt = get_best_pix_fmt( img_fmt, ('yuv420p', 'rgba', 'rgb24', 'gray', 'bgr24', 'bgra')) swscale = SWScale( iw=img_w, ih=img_h, ifmt=img_fmt, ow=0, oh=0, ofmt=ofmt) img = swscale.scale(img) img_fmt = img.get_pixel_format() kivy_ofmt = { 'yuv420p': 'yuv420p', 'rgba': 'rgba', 'rgb24': 'rgb', 'gray': 'luminance', 'bgr24': 'bgr', 'bgra': 'bgra'}[img_fmt] if kivy_ofmt == 'yuv420p': w2 = int(img_w / 2) h2 = int(img_h / 2) tex_y = Texture.create(size=(img_w, img_h), colorfmt='luminance') tex_u = Texture.create(size=(w2, h2), colorfmt='luminance') tex_v = Texture.create(size=(w2, h2), colorfmt='luminance') with canvas: fbo = Fbo(size=(img_w, img_h)) with fbo: BindTexture(texture=tex_u, index=1) BindTexture(texture=tex_v, index=2) Rectangle(size=fbo.size, texture=tex_y) fbo.shader.fs = CeedDataReader._YUV_RGB_FS fbo['tex_y'] = 0 fbo['tex_u'] = 1 fbo['tex_v'] = 2 tex = fbo.texture dy, du, dv, _ = img.to_memoryview() tex_y.blit_buffer(dy, colorfmt='luminance') tex_u.blit_buffer(du, colorfmt='luminance') tex_v.blit_buffer(dv, colorfmt='luminance') else: tex = Texture.create(size=(img_w, img_h), colorfmt=kivy_ofmt) tex.blit_buffer(img.to_memoryview()[0], colorfmt=kivy_ofmt) tex.flip_vertical() with canvas: StencilPush() Rectangle(pos=pos, size=size) StencilUse() PushMatrix() center = pos[0] + size[0] / 2, pos[1] + size[1] / 2 if rotation: Rotate(angle=rotation, axis=(0, 0, 1), origin=center) if scale: Scale(scale, scale, 1, origin=center) if translation: Translate(*translation) if transform_matrix is not None: mat = Matrix() mat.set(array=transform_matrix) m = MatrixInstruction() m.matrix = mat Rectangle(size=(img_w, img_h), texture=tex, pos=pos) PopMatrix() StencilUnUse() Rectangle(pos=pos, size=size) StencilPop()