コード例 #1
0
ファイル: ripple_behavior.py プロジェクト: zxllkada/KivyMD
 def lay_canvas_instructions(self):
     if self._no_ripple_effect:
         return
     with self.canvas.after:
         StencilPush(group="circular_ripple_behavior")
         self.stencil = Ellipse(
             size=(
                 self.width * self.ripple_scale,
                 self.height * self.ripple_scale,
             ),
             pos=(
                 self.center_x - (self.width * self.ripple_scale) / 2,
                 self.center_y - (self.height * self.ripple_scale) / 2,
             ),
             group="circular_ripple_behavior",
         )
         StencilUse(group="circular_ripple_behavior")
         self.col_instruction = Color(rgba=self.ripple_color)
         self.ellipse = Ellipse(
             size=(self._ripple_rad, self._ripple_rad),
             pos=(
                 self.center_x - self._ripple_rad / 2.0,
                 self.center_y - self._ripple_rad / 2.0,
             ),
             group="circular_ripple_behavior",
         )
         StencilUnUse(group="circular_ripple_behavior")
         Ellipse(pos=self.pos,
                 size=self.size,
                 group="circular_ripple_behavior")
         StencilPop(group="circular_ripple_behavior")
         self.bind(ripple_color=self._set_color,
                   _ripple_rad=self._set_ellipse)
コード例 #2
0
 def lay_canvas_instructions(self):
     with self.canvas.after:
         StencilPush()
         self.stencil = Ellipse(
             size=(
                 self.width * self.ripple_scale,
                 self.height * self.ripple_scale,
             ),
             pos=(
                 self.center_x - (self.width * self.ripple_scale) / 2,
                 self.center_y - (self.height * self.ripple_scale) / 2,
             ),
         )
         StencilUse()
         self.col_instruction = Color(rgba=self.ripple_color)
         self.ellipse = Ellipse(
             size=(self._ripple_rad, self._ripple_rad),
             pos=(
                 self.center_x - self._ripple_rad / 2.0,
                 self.center_y - self._ripple_rad / 2.0,
             ),
         )
         StencilUnUse()
         Ellipse(pos=self.pos, size=self.size)
         StencilPop()
         self.bind(ripple_color=self._set_color,
                   _ripple_rad=self._set_ellipse)
コード例 #3
0
 def on_touch_down(self, touch):
     if self.collide_point(touch.x, touch.y):
         # self.anim_complete(self, self)
         self.ripple_pos = ripple_pos = (touch.x, touch.y)
         Animation.cancel_all(self, 'ripple_rad', 'ripple_color')
         rc = self.ripple_color
         ripple_rad = self.ripple_rad
         self.ripple_color = [rc[0], rc[1], rc[2], 1.]
         anim = Animation(
             ripple_rad=max(self.width, self.height) * self.ripple_scale,
             t=self.ripple_func_in,
             ripple_color=[rc[0], rc[1], rc[2], self.fade_to_alpha],
             duration=self.ripple_duration_in)
         anim.bind(on_complete=self.anim_complete)
         anim.start(self)
         with self.canvas:
             StencilPush()
             Rectangle(size=self.size, pos=self.pos)
             StencilUse()
             self.col_instruction = Color(rgba=self.ripple_color,
                                          group='one')
             self.ellipse = Ellipse(size=(ripple_rad, ripple_rad),
                                    pos=(ripple_pos[0] - ripple_rad / 2.,
                                         ripple_pos[1] - ripple_rad / 2.),
                                    group='one')
             StencilUnUse()
             Rectangle(size=self.size, pos=self.pos)
             StencilPop()
         self.bind(ripple_color=self.set_color,
                   ripple_pos=self.set_ellipse,
                   ripple_rad=self.set_ellipse)
     return super(TouchRippleBehavior, self).on_touch_down(touch)
コード例 #4
0
ファイル: ripple_behavior.py プロジェクト: zxllkada/KivyMD
 def lay_canvas_instructions(self):
     if self._no_ripple_effect:
         return
     with self.canvas.after:
         if hasattr(self, "radius"):
             self._round_rad = self.radius
         StencilPush(group="rectangular_ripple_behavior")
         RoundedRectangle(
             pos=self.pos,
             size=self.size,
             radius=self._round_rad,
             group="rectangular_ripple_behavior",
         )
         StencilUse(group="rectangular_ripple_behavior")
         self.col_instruction = Color(rgba=self.ripple_color,
                                      group="rectangular_ripple_behavior")
         self.ellipse = Ellipse(
             size=(self._ripple_rad, self._ripple_rad),
             pos=(
                 self.ripple_pos[0] - self._ripple_rad / 2.0,
                 self.ripple_pos[1] - self._ripple_rad / 2.0,
             ),
             group="rectangular_ripple_behavior",
         )
         StencilUnUse(group="rectangular_ripple_behavior")
         RoundedRectangle(
             pos=self.pos,
             size=self.size,
             radius=self._round_rad,
             group="rectangular_ripple_behavior",
         )
         StencilPop(group="rectangular_ripple_behavior")
     self.bind(ripple_color=self._set_color, _ripple_rad=self._set_ellipse)
コード例 #5
0
    def on_touch_down(self, touch):
        if self in touch.ud:
            self.anim_complete(self, self)
            self.ripple_pos = ripple_pos = (touch.x, touch.y)
            Animation.cancel_all(self, 'ripple_rad', 'ripple_color')
            rc = self.ripple_color
            ripple_rad = self.ripple_rad
            self.ripple_color = [rc[0], rc[1], rc[2], 1.]
            anim = Animation(
                ripple_rad=max(self.width, self.height) * self.ripple_scale,
                t=self.ripple_func_in,
                ripple_color=[rc[0], rc[1], rc[2], self.fade_to_alpha],
                duration=self.ripple_duration_in)
            anim.start(self)
            with self.canvas.after:
                x, y = self.to_window(*self.pos)
                width, height = self.size

                if self.orientation == 'horizontal':
                    ellipse_pos = (self.value_pos[0] - sp(16),
                                   self.center_y - sp(17))
                    stencil_pos = (self.x + self.padding + sp(2),
                                   self.center_y - sp(7))
                    stencil_size = (self.width - self.padding * 2 - sp(4),
                                    sp(14))
                else:
                    ellipse_pos = (self.center_x - sp(17),
                                   self.value_pos[1] - sp(16))
                    stencil_pos = (self.center_x - sp(7),
                                   self.y + self.padding + sp(2))
                    stencil_size = (sp(14),
                                    self.height - self.padding * 2 - sp(4))

                StencilPush()
                Rectangle(pos=stencil_pos, size=stencil_size)
                self.slider_stencil = Ellipse(pos=ellipse_pos,
                                              size=(sp(32), sp(32)))
                StencilUse(op='lequal')
                self.col_instruction = Color(rgba=self.ripple_color)
                self.ellipse = Ellipse(size=(ripple_rad, ripple_rad),
                                       pos=(ripple_pos[0] - ripple_rad / 2.,
                                            ripple_pos[1] - ripple_rad / 2.))
                StencilUnUse()
                Rectangle(pos=stencil_pos, size=stencil_size)
                self.slider_stencil_unuse = Ellipse(pos=ellipse_pos,
                                                    size=(sp(32), sp(32)))

                StencilPop()
            self.bind(ripple_color=self.set_color,
                      ripple_pos=self.set_ellipse,
                      ripple_rad=self.set_ellipse)
        return super(SliderTouchRippleBehavior, self).on_touch_down(touch)
コード例 #6
0
 def lay_canvas_instructions(self):
     with self.canvas.after:
         StencilPush()
         Rectangle(pos=self.pos, size=self.size)
         StencilUse()
         self.col_instruction = Color(rgba=self.ripple_color)
         self.ellipse = \
             Ellipse(size=(self.ripple_rad, self.ripple_rad),
                     pos=(self.ripple_pos[0] - self.ripple_rad / 2.,
                          self.ripple_pos[1] - self.ripple_rad / 2.))
         StencilUnUse()
         Rectangle(pos=self.pos, size=self.size)
         StencilPop()
     self.bind(ripple_color=self._set_color, ripple_rad=self._set_ellipse)
コード例 #7
0
    def on_touch_down(self, touch):
        if self in touch.ud:
            self.anim_complete(self, self)
            self.ripple_pos = ripple_pos = (touch.x, touch.y)
            Animation.cancel_all(self, 'ripple_rad', 'ripple_color')
            rc = self.ripple_color
            ripple_rad = self.ripple_rad
            self.ripple_color = [rc[0], rc[1], rc[2], .16]
            anim = Animation(
                ripple_rad=max(self.width, self.height) * self.ripple_scale,
                t=self.ripple_func_in,
                ripple_color=[rc[0], rc[1], rc[2], self.fade_to_alpha],
                duration=self.ripple_duration_in)
            anim.start(self)
            with self.canvas.after:
                x, y = self.to_window(*self.pos)
                width, height = self.size
                #In python 3 the int cast will be unnecessary
                pos = (int(round(x)), int(round(y)))
                size = (int(round(width)), int(round(height)))

                if _has_scissor_instr:
                    ScissorPush(x=pos[0],
                                y=pos[1],
                                width=size[0],
                                height=size[1])
                else:
                    StencilPush()
                    Rectangle(pos=(int(round(x)), int(round(y))),
                              size=(int(round(width)), int(round(height))))

                    StencilUse()

                self.col_instruction = Color(rgba=self.ripple_color)
                self.ellipse = Ellipse(size=(ripple_rad, ripple_rad),
                                       pos=(ripple_pos[0] - ripple_rad / 2.,
                                            ripple_pos[1] - ripple_rad / 2.))

                if _has_scissor_instr:
                    ScissorPop()
                else:
                    StencilUnUse()
                    Rectangle(pos=(int(round(x)), int(round(y))),
                              size=(int(round(width)), int(round(height))))
                    StencilPop()

            self.bind(ripple_color=self.set_color,
                      ripple_pos=self.set_ellipse,
                      ripple_rad=self.set_ellipse)
        return super(TouchRippleBehavior, self).on_touch_down(touch)
コード例 #8
0
ファイル: backend_kivy.py プロジェクト: MBM1607/muhasib
 def draw_image(self, gc, x, y, im):
     '''Render images that can be displayed on a matplotlib figure.
        These images are generally called using imshow method from pyplot.
        A Texture is applied to the FigureCanvas. The position x, y is
        given in matplotlib coordinates.
     '''
     # Clip path to define an area to mask.
     clippath, clippath_trans = gc.get_clip_path()
     # Normal coordinates calculated and image added.
     x = self.widget.x + x
     y = self.widget.y + y
     bbox = gc.get_clip_rectangle()
     if bbox is not None:
         l, b, w, h = bbox.bounds
     else:
         l = 0
         b = 0
         w = self.widget.width
         h = self.widget.height
     h, w = im.get_size_out()
     rows, cols, image_str = im.as_rgba_str()
     texture = Texture.create(size=(w, h))
     texture.blit_buffer(image_str, colorfmt='rgba', bufferfmt='ubyte')
     if clippath is None:
         with self.widget.canvas:
             Color(1.0, 1.0, 1.0, 1.0)
             Rectangle(texture=texture, pos=(x, y), size=(w, h))
     else:
         if _mpl_ge_2_0:
             polygons = clippath.to_polygons(clippath_trans,
                                             closed_only=False)
         else:
             polygons = clippath.to_polygons(clippath_trans)
         list_canvas_instruction = self.get_path_instructions(
             gc, polygons, rgbFace=(1.0, 1.0, 1.0, 1.0))
         for widget, instructions in list_canvas_instruction:
             widget.canvas.add(StencilPush())
             widget.canvas.add(instructions)
             widget.canvas.add(StencilUse())
             widget.canvas.add(Color(1.0, 1.0, 1.0, 1.0))
             widget.canvas.add(
                 Rectangle(texture=texture, pos=(x, y), size=(w, h)))
             widget.canvas.add(StencilUnUse())
             widget.canvas.add(StencilPop())
コード例 #9
0
 def lay_canvas_instructions(self):
     if self._no_ripple_effect:
         return
     with self.canvas.after:
         StencilPush()
         RoundedRectangle(pos=self.pos, size=self.size, radius = self.radius)
         StencilUse()
         self.col_instruction = Color(rgba=self.ripple_color)
         self.ellipse = Ellipse(
             size=(self._ripple_rad, self._ripple_rad),
             pos=(
                 self.ripple_pos[0] - self._ripple_rad / 2.0,
                 self.ripple_pos[1] - self._ripple_rad / 2.0,
             ),
         )
         StencilUnUse()
         RoundedRectangle(pos=self.pos, size=self.size, radius = self.radius)
         StencilPop()
     self.bind(ripple_color=self._set_color, _ripple_rad=self._set_ellipse)
コード例 #10
0
 def lay_canvas_instructions(self):
     with self.canvas.after:
         StencilPush()
         min_dim = min(self.size)
         self.stencil = Ellipse(size=(min_dim * self.ripple_scale,
                                      min_dim * self.ripple_scale),
                                pos=(self.center_x - (
                                    min_dim * self.ripple_scale) / 2,
                                     self.center_y - (
                                             min_dim * self.ripple_scale)/2))
         StencilUse()
         self.col_instruction = Color(rgba=self.ripple_color)
         self.ellipse = Ellipse(size=(self.ripple_rad, self.ripple_rad),
                                pos=(self.center_x - self.ripple_rad / 2.,
                                     self.center_y - self.ripple_rad / 2.))
         StencilUnUse()
         Ellipse(pos=self.pos, size=self.size)
         StencilPop()
         self.bind(ripple_color=self._set_color,
                   ripple_rad=self._set_ellipse)
コード例 #11
0
 def draw(self, **kwargs):
     self.canvas.clear()
     if not self.place:
         with self.canvas:
             Color(*SOMA_COLOR)
             self.outline = Ellipse()
             Color(*SOMA_COLOR)
             self.soma = Ellipse()
     elif self.place:
         with self.canvas:
             StencilPush()
             self.mask = Ellipse()
             StencilUse()
             Color(*OUTLINE_COLOR)
             self.outline = Ellipse()
             Color(*SOMA_COLOR)
             self.soma = Ellipse()
             Color(*OUTLINE_COLOR)
             self.ntLevel = Rectangle()
             StencilUnUse()
             StencilPop()
コード例 #12
0
    def on_touch_down(self, touch):
        if touch.is_mouse_scrolling:
            return False
        if not self.collide_point(touch.x, touch.y):
            return False

        self.ripple_rad = self.ripple_rad_default
        if hasattr(self, 'disabled'):
            if not self.disabled:
                Animation.cancel_all(self, 'ripple_rad', 'ripple_color',
                                     'rect_color')
                ripple_rad = self.ripple_rad

                if not hasattr(self, 'ripple_color'):
                    self.rip_color = [rc[0], rc[1], rc[2], self.ripple_alpha]
                else:
                    self.rip_color = self.ripple_color
                    self.rip_color[3] = self.ripple_alpha

                with self.canvas.after:
                    StencilPush()
                    Ellipse(size=(self.width * self.ripple_scale,
                                  self.height * self.ripple_scale),
                            pos=(self.center_x -
                                 (self.width * self.ripple_scale) / 2,
                                 self.center_y -
                                 (self.height * self.ripple_scale) / 2))
                    StencilUse()
                    self.col_instruction = Color(rgba=self.rip_color)
                    self.ellipse = Ellipse(
                        size=(ripple_rad, ripple_rad),
                        pos=(self.center_x - ripple_rad / 2.,
                             self.center_y - ripple_rad / 2.))
                    StencilUnUse()
                    Ellipse(pos=self.pos, size=self.size)
                    StencilPop()
                self.bind(rip_color=self._set_color,
                          ripple_rad=self._set_ellipse)
                self.start_rippeling(touch)
        return super(CircularRippleBehavior, self).on_touch_down(touch)
コード例 #13
0
ファイル: __init__.py プロジェクト: cplab/ceed
    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()
コード例 #14
0
ファイル: __init__.py プロジェクト: cplab/ceed
    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))
コード例 #15
0
ファイル: __init__.py プロジェクト: cplab/ceed
    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()