有没有一种方法可以使TextInput中的文本颜色以奇特的形式取决于背景?

时间:2019-05-14 09:48:42

标签: python kivy

我正在使用Kivy的TextInput,并在其后面有背景图片。 由于有背景图片-上方的文字不清楚(例如,黑色背景上的黑色文字等)。

有没有一种方法可以使文本颜色与背景颜色相反?

请注意,背景不是纯色图像,而是普通图像。谢谢!

此外,我希望有文字轮廓,以便于阅读。尝试了text_outline属性,但是它用于标签而不是textInputs,是否有替代方法?

再次,谢谢!

2 个答案:

答案 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)

一般算法如下:

  1. 查找图像的平均颜色
  2. 找到互补色或对比色

  3. 将text_input的颜色设置为对比色。

1和2的实现可能非常复杂。 在此示例中,我将仅显示一个粗略的草图。当然,您可以找到或实现更有效的功能。

  1. 找到图像的主色:
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颜色。

  1. 找到互补色/对比色。
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图像文件,文本将自动将其颜色更改为黑色或白色。 enter image description here