File: imageutils.py

package info (click to toggle)
wxpython4.0 4.2.3%2Bdfsg-2
  • links: PTS, VCS
  • area: main
  • in suites: forky, sid, trixie
  • size: 221,752 kB
  • sloc: cpp: 962,555; python: 230,573; ansic: 170,731; makefile: 51,756; sh: 9,342; perl: 1,564; javascript: 584; php: 326; xml: 200
file content (163 lines) | stat: -rw-r--r-- 4,396 bytes parent folder | download | duplicates (4)
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
#----------------------------------------------------------------------
# Name:        wx.lib.imageutils
# Purpose:     A collection of functions for simple image manipulations
#
# Author:      Robb Shecter
#
# Created:     7-Nov-2002
# Copyright:   (c) 2002 by
# Licence:     wxWindows license
# Tags:        phoenix-port, unittest, documented
#----------------------------------------------------------------------

"""
This module contains a collection of functions for simple image manipulations.


Description
===========

This module contains a collection of functions for simple image manipulations.
The 2 functions defined here (:func:`grayOut`, :func:`makeGray` and :func:`stepColour`)
can be used to convert a given image into a grey-scale representation and to
darken/lighten a specific wxPython :class:`wx.Colour`.


Usage
=====

Sample usage::

    import wx
    from wx.lib.imageutils import grayOut, stepColour

    app = wx.App(0)

    bmp = wx.ArtProvider.GetBitmap(wx.ART_INFORMATION, wx.ART_OTHER, (32, 32))
    disabled_bmp = wx.Bitmap(grayOut(bmp.ConvertToImage()))

    colour = wx.Colour(100, 120, 130)

    # Darker
    dark_colour = stepColour(colour, 50)

    # Lighter
    light_colour = stepColour(colour, 120)

    app.MainLoop()

"""


import wx

def grayOut(anImage):
    """
    Convert the given image (in place) to a grayed-out
    version, appropriate for a 'disabled' appearance.

    :param wx.Image `anImage`: the image we want to convert to gray-scale.

    :rtype: :class:`wx.Image`
    :returns: The modified (greyed out) image.

    .. note:: the image is converted in place, i.e. the input image will
       be modified to a greyed out version.

    """

    factor = 0.7        # 0 < f < 1.  Higher is grayer.
    if anImage.HasMask():
        maskColor = (anImage.GetMaskRed(), anImage.GetMaskGreen(), anImage.GetMaskBlue())
    else:
        maskColor = None
    if anImage.HasAlpha():
        alpha = anImage.GetAlpha()
    else:
        alpha = None

    data = anImage.GetData()

    for i in range(0, len(data), 3):
        pixel = (data[i], data[i+1], data[i+2])
        pixel = makeGray(pixel, factor, maskColor)
        for x in range(3):
            data[i+x] = pixel[x]
    anImage.SetData(data)  # ''.join(map(chr, data)))
    if alpha:
        anImage.SetAlpha(alpha)


def makeGray(rgb, factor, maskColor):
    """
    Make a pixel grayed-out. If the pixel matches the maskColor, it won't be
    changed.

    :param tuple `rgb`: a tuple of red, green, blue integers, defining the pixel :class:`wx.Colour`;
    :param float `factor`: the amount for which we want to grey out a pixel colour;
    :param `maskColor`: the mask colour.

    :type `maskColor`: tuple or :class:`wx.Colour`.

    :rtype: tuple
    :returns: An RGB tuple with the greyed out pixel colour.
    """

    if rgb != maskColor:
        return tuple([int((230 - x)*factor) + x for x in rgb])
    else:
        return rgb



def stepColour(c, step):
    """
    An utility function that simply darkens or lightens a
    color, based on the specified step value.  A step of 0 is
    completely black and a step of 200 is totally white, and 100
    results in the same color as was passed in.

    :param wx.Colour `c`: the input colour to be modified (darkened or lightened);
    :param integer `step`: the step value.

    :rtype: :class:`wx.Colour`
    :returns: A new colour, darkened or lightened depending on the input `step` value.
    """

    def _blendColour(fg, bg, dstep):
        result = bg + (dstep * (fg - bg))
        if result < 0:
            result = 0
        if result > 255:
            result = 255
        return result

    if step == 100:
        return c

    r = c.Red()
    g = c.Green()
    b = c.Blue()

    # step is 0..200 where 0 is completely black
    # and 200 is completely white and 100 is the same
    # convert that to a range of -1.0 .. 1.0
    step = min(step, 200)
    step = max(step, 0)
    dstep = (step - 100.0)/100.0

    if step > 100:
        # blend with white
        bg = 255.0
        dstep = 1.0 - dstep  # 0 = transparent fg; 1 = opaque fg
    else:
        # blend with black
        bg = 0.0
        dstep = 1.0 + dstep;  # 0 = transparent fg; 1 = opaque fg

    r = _blendColour(r, bg, dstep)
    g = _blendColour(g, bg, dstep)
    b = _blendColour(b, bg, dstep)

    return wx.Colour(int(r), int(g), int(b))