examples/image-scaling.py
This is one of the example scripts included
with Shady. These scripts can be run conventionally like any
normal Python script, or you can choose to run them as
interactive tutorials, for example with python -m Shady demo image-scaling
#!/usr/bin/env python
# $BEGIN_SHADY_LICENSE$
#
# This file is part of the Shady project, a Python framework for
# real-time manipulation of psychophysical stimuli for vision science.
#
# Copyright (c) 2017-2022 Jeremy Hill, Scott Mooney
#
# Shady is free software: you can redistribute it and/or modify it
# under the terms of the GNU General Public License as published by
# the Free Software Foundation, either version 3 of the License, or
# (at your option) any later version.
#
# This program is distributed in the hope that it will be useful,
# but WITHOUT ANY WARRANTY; without even the implied warranty of
# MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the
# GNU General Public License for more details.
#
# You should have received a copy of the GNU General Public License
# along with this program. If not, see http://www.gnu.org/licenses/ .
#
# $END_SHADY_LICENSE$
#: Demonstrates interpolated and non-interpolated image scaling
"""
This demo displays two well-known images whose interpretation
depends on their scaling, and allows you to manipulate scaling
using the `-` and `+` keys.
This demo requires the third-party package `numpy`.
"""#.
if __name__ == '__main__':
"""
First deal with the demo's command-line arguments,
if any:
"""#:
import Shady
cmdline = Shady.WorldConstructorCommandLine()
cmdline.Help().Finalize()
Shady.Require( 'numpy' ) # die with an informative error if this is missing
"""
Create a World:
"""#:
w = Shady.World( **cmdline.opts )
"""
Here's a familiar pixellated stimulus:
"""#:
maxScale = int( min( w.size / [ 28, 18 ] ) )
s = w.Stimulus( [
[ 218, 231, 224, 176, 79, 36, 53, 43, 33, 67, 241, 223, 231, 220 ],
[ 221, 238, 194, 77, 56, 160, 106, 68, 29, 41, 97, 206, 240, 226 ],
[ 231, 234, 82, 64, 120, 229, 208, 222, 105, 46, 35, 191, 231, 231 ],
[ 224, 223, 70, 83, 147, 157, 211, 206, 199, 92, 107, 136, 191, 235 ],
[ 227, 163, 52, 86, 143, 176, 177, 182, 177, 200, 120, 81, 152, 228 ],
[ 223, 66, 108, 57, 88, 132, 46, 57, 103, 64, 46, 75, 166, 233 ],
[ 224, 113, 154, 70, 83, 83, 80, 83, 126, 73, 70, 201, 229, 232 ],
[ 224, 138, 196, 154, 91, 173, 180, 192, 206, 126, 86, 216, 220, 231 ],
[ 220, 230, 100, 117, 40, 93, 175, 140, 102, 77, 100, 221, 222, 226 ],
[ 204, 219, 153, 52, 46, 90, 102, 132, 127, 69, 129, 216, 217, 221 ],
[ 200, 220, 197, 91, 41, 104, 150, 142, 96, 54, 154, 227, 220, 219 ],
[ 157, 179, 150, 97, 52, 52, 52, 71, 85, 53, 115, 223, 226, 228 ],
[ 153, 130, 137, 38, 207, 44, 32, 11, 16, 64, 228, 229, 244, 235 ],
[ 150, 111, 51, 13, 94, 221, 92, 104, 159, 124, 192, 228, 226, 223 ],
[ 72, 52, 57, 54, 41, 39, 22, 35, 77, 71, 69, 205, 223, 226 ],
[ 71, 52, 71, 57, 37, 40, 41, 110, 65, 51, 48, 46, 82, 201 ],
[ 52, 68, 44, 49, 43, 40, 65, 116, 112, 109, 101, 65, 43, 147 ],
[ 83, 29, 25, 18, 52, 42, 38, 75, 228, 237, 225, 156, 39, 218 ],
],
linearMagnification = False,
scale = maxScale,
pos = w.Place( -1, 0 ),
anchor=( -1, 0 ),
)
"""
Here's another familiar image:
"""#:
s2 = w.Stimulus(
Shady.EXAMPLE_MEDIA.EinsteinMonroe,
pos = w.Place( +1, 0 ),
anchor = ( +1, 0 ),
)
"""
The following dynamic property assignment will ensure
the two images are always scaled to the same height.
(We cannot use the more-efficient mechanism of property
sharing here, since `.scaledHeight` is not a fully-
fledged `ManagedProperty`, but the dynamic will do
fine.) Since the default value of `.scaledAspectRatio`
is `'fixed'`, the `.scaledWidth` property will be
automatically adjusted to preserve aspect ratio.
"""#:
s2.scaledHeight = lambda t: s.scaledHeight
"""
Finally we'll install an event handler for manipulating
the images via the keyboard:
"""#:
@w.EventHandler( slot=-1 )
def eh( self, event ):
if event >> "kp[i]":
s.linearMagnification = not s.linearMagnification
if event >> "kp[+] ka[+] kp[=] ka[=]":
s.scale = min( maxScale, round( min( s.scale ) ) + 1 )
if event >> "kp[-] ka[-]":
s.scale = max( 1, round( min( s.scale ) ) - 1 )
""#>
print( """
Press - / + to adjust image scaling
Press I to toggle linear interpolation on/off in the left image
""")
Shady.AutoFinish( w ) # tidy up, in case we didn't get here via `python -m Shady`