我正在使用Kivy的TextInput,并在其后面有背景图片。 由于有背景图片-上方的文字不清楚(例如,黑色背景上的黑色文字等)。
有没有一种方法可以使文本颜色与背景颜色相反?
请注意,背景不是纯色图像,而是普通图像。谢谢!
此外,我希望有文字轮廓,以便于阅读。尝试了text_outline属性,但是它用于标签而不是textInputs,是否有替代方法?
再次,谢谢!
答案 0 :(得分:1)
不确定如何根据您的描述更改文本颜色。您是说要根据其背后的颜色更改文本颜色吗?像E
的顶部可能是白色,而同一E
的底部可能是黑色?
但是我认为您可以通过将其子类添加到TextInput
来添加outline属性:
from kivy.core.text import Label
from kivy.properties import NumericProperty, ListProperty
from kivy.uix.textinput import TextInput
class TextInputOutline(TextInput):
outline_width = NumericProperty(0)
outline_color = ListProperty((0,0,0))
def _get_line_options(self):
# Get or create line options, to be used for Label creation
if self._line_options is None:
self._line_options = kw = {
'font_size': self.font_size,
'font_name': self.font_name,
'anchor_x': 'left',
'anchor_y': 'top',
'padding_x': 0,
'padding_y': 0,
'padding': (0, 0),
'outline_width': self.outline_width,
'outline_color': self.outline_color}
self._label_cached = Label(**kw)
return self._line_options
上面的_get_line_options
方法将覆盖TextInput
中的相同方法。唯一的区别是包含了outline
属性。使用此TextInputOutline
,您可以指定轮廓线的厚度和颜色,例如:
TextInputOutline:
text: 'This is a Test'
foreground_color: (1, 1, 1, 1)
outline_color: (0, 0, 0)
outline_width: 1
请注意,此方法优先于以_
开头的方法,因此无法保证如果将来TextInput
进行某些更新Kivy
时,此方法仍然有效。
答案 1 :(得分:1)
一般算法如下:
找到互补色或对比色
将text_input的颜色设置为对比色。
1和2的实现可能非常复杂。 在此示例中,我将仅显示一个粗略的草图。当然,您可以找到或实现更有效的功能。
from PIL import Image as I
def average_color(image_fn):
im = I.open(image_fn)
im = im.convert('RGB')
#comment the above if you don't use images with opacity
new_im = im.resize((1, 1))
pixels = new_im.getpixel((0, 0))
print pixels
return pixels
这是非常非常粗糙的方式。 我建议图像具有正方形的形状。 然后使用PIL,我只需将其大小更改为1像素(1x1),然后我就获得了该像素的rgb颜色。
from colorsys import rgb_to_hls as rgb2hls
from colorsys import hls_to_rgb as hls2rgb
def contrast(rgb):
h,l,s = rgb2hls(*rgb)
new_l = 0 if l>=0.5 else 1
new_rgb = hls2rgb(h, new_l,s)
return new_rgb
此函数获取RGB像素,然后将其转换为HLS,然后将“亮度”设置为0或1(尽可能远离当前值),然后将其转换回RGB,并返回此值。因此,我们将获得白色或黑色文本颜色,具体取决于哪种颜色与当前图像的对比度更大。
现在让我们将这些算法添加到kivy应用程序中:
from __future__ import division
from kivy.app import App
from kivy.lang import Builder
from kivy.uix.image import Image
from kivy.core.window import Window
from PIL import Image as I
from colorsys import rgb_to_hls as rgb2hls
from colorsys import hls_to_rgb as hls2rgb
KV = """
FloatLayout
MyImage
id: image
text_input:text_input
#source: 'im.png'
MyTextInput
id: text_input
<MyTextInput@TextInput>
font_size: 40
background_normal : ''
background_active: ''
background_color: 0,0,0,0
text: 'this is some text. Drag and drop an image here. '*20
"""
def average_color(image_fn):
im = I.open(image_fn)
im = im.convert('RGB')
#comment the above if you don't use images with opacity
new_im = im.resize((1, 1))
pixels = new_im.getpixel((0, 0))
print pixels
return pixels
def contrast(rgb):
h,l,s = rgb2hls(*rgb)
new_l = 0 if l>=0.5 else 1
new_rgb = hls2rgb(h, new_l,s)
return new_rgb
class MyImage(Image):
def on_source(self, inst, fn):
aver = [i/255 for i in average_color(fn)]
contrast_rgba = [i for i in contrast(aver)]+[1]
self.text_input.foreground_color = contrast_rgba
class MyApp(App):
def build(self):
self.root = Builder.load_string(KV)
Window.bind(on_dropfile=self.manage_dropfile)
def is_image(self, fn):
if fn[-4:] in ['.png', '.jpg', 'jpeg']: return True
return False
def manage_dropfile(self, window, fn):
fn = fn.decode('UTF-8')
if self.is_image(fn):
self.root.ids.image.source = fn
MyApp().run()
最重要的是,我们创建了一个MyImage类,其中在on_source()方法中(每次更改图像源时),我们获取平均颜色值,然后获取对比色,最后更改前景色。
我还实现了图像的拖放。您可以从计算机上的某个文件夹中删除任何jpg / png图像文件,文本将自动将其颜色更改为黑色或白色。