猕猴桃削减文本形状

时间:2020-05-13 19:07:21

标签: python kivy

正如画布说明中的Stencil和Scissor(在我看来具有相同的效果)用于创建蒙版并在蒙版上绘制一样,我想知道是否有人可以实现这种效果:

在背景图像上绘制任何形状(到目前为止非常容易)。然后从形状中切出文本,以便在背景上浏览。

有什么解决办法吗?还是我错过的任何kivy / openGL指令?

1 个答案:

答案 0 :(得分:0)

这是您想要的东西。这是一种蛮力方法,它使kivy.core.text.Label的文本透明,然后在画布Rectangle中使用该纹理:

from kivy.app import App
from kivy.clock import Clock
from kivy.graphics.context_instructions import Color
from kivy.graphics.texture import Texture
from kivy.graphics.vertex_instructions import Rectangle
from kivy.lang import Builder
from kivy.uix.floatlayout import FloatLayout
from kivy.core.text import Label as CoreLabel

class MyWidget(FloatLayout):
    pass

Builder.load_string('''
<MyWidget>:
    Image:
        source: 'tester.png'
        allow_stretch: True
        keep_ratio: True
''')


class TestApp(App):
    def build(self):
        Clock.schedule_once(self.doit)
        return MyWidget()

    def doit(self, dt):
        # build a Rectangle half the size and centered on the root (MyWidget)
        size = (self.root.width/2, self.root.height/2)
        pos = (self.root.x + (self.root.width - size[0])/2, self.root.y + (self.root.height - size[1])/2)
        with self.root.canvas.after:
            Color(1,1,1,1)
            self.rect = Rectangle(pos=pos, size=size)

        # create a Texture with desired text and desired size
        label = CoreLabel(text='Hello', font_name='Roboto-Bold', font_size=300, valign='center', halign='center',
                          size=self.root.size, color=(1,1,1,1))
        label.refresh()

        # make the actual text transparent, and assign the new Texture to the Rectangle
        self.rect.texture =  self.make_text_transparent(label.texture, (255, 0, 0, 255))

    def make_text_transparent(self, texture, bg_color):
        # bg_color is a 4 tuple of byte values in the range 0-255
        # The normal Label texture is transparent except for the text itself
        # This code changes the texture to make the text transparent, and everything else
        # gets set to bg_color
        pixels = list(texture.pixels)
        for index in range(3, len(pixels)-4, 4):
            if pixels[index] == 0:
                # change transparent pixels to the bg_color
                pixels[index-3:index+1] = bg_color
            else:
                # make the text itself transparent
                pixels[index] = 0

        # create a new texture, blit the new pixels, and return the new texture
        new_texture = Texture.create(size=texture.size, colorfmt='rgba')
        new_texture.blit_buffer(bytes(pixels), colorfmt='rgba', bufferfmt='ubyte')
        new_texture.flip_vertical()
        return new_texture

TestApp().run()

您可以通过使用其他纹理代替bg_color并通过将透明的Label像素设置为所提供的Texture中的相应像素来对此进行概括。