正如画布说明中的Stencil和Scissor(在我看来具有相同的效果)用于创建蒙版并在蒙版上绘制一样,我想知道是否有人可以实现这种效果:
在背景图像上绘制任何形状(到目前为止非常容易)。然后从形状中切出文本,以便在背景上浏览。
有什么解决办法吗?还是我错过的任何kivy / openGL指令?
答案 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中的相应像素来对此进行概括。