Welcome!
This is the community forum for my apps Pythonista and Editorial.
For individual support questions, you can also send an email. If you have a very short question or just want to say hello — I'm @olemoritz on Twitter.
Is it possible to tint iconicons using scene.image?
-
When using scene.image to draw iconicons they appear black. Using scene.tint makes no difference. I would like them to appear blue. Any ideas?
A workaround is to use ui Buttons. But it seems overkill to use buttons just to draw a passive icon.
from scene import * class MyScene (Scene): def draw(self): background(1, 1, 0) tint(0, 0, 1) image('ionicons-checkmark-circled-32', 300, 300) run(MyScene())
-
@inoddy, maybe you can use
PIL.Image
to load that image and then tint it using some PIL functions? -
Did you have something specific in mind? I tried this:
from scene import * from PIL import Image from PIL import ImageOps class MyScene (Scene): def draw(self): background(1, 1, 0) tint(0, 0, 1) img = Image.open('ionicons-arrow-down-c-32').convert('L') img = ImageOps.colorize(img, 'blue', 'white').convert('RGBA') img = load_pil_image(img) image(img, 300, 300) run(MyScene())
but it coloured the whole box blue instead of the part of the icon that I wanted blue. I hope there's something better than grabbing all the pixels and changing them individually.
-
The only way I know how to do this, is to loop over all of the pixels :P
from scene import * from PIL import Image class MyScene (Scene): def setup(self): img = Image.open('ionicons-arrow-down-c-32').convert('RGBA') pixeldata = img.load() for y in xrange(img.size[1]): for x in xrange(img.size[0]): if pixeldata[x, y] != (0,0,0,0): r, g, b, a = pixeldata[x, y] pixeldata[x, y] = (0, 0, 255, a) self.img = load_pil_image(img) def draw(self): background(1,1,0) image(self.img, 300, 300) run(MyScene())
-
That works quite well (if a little slow - precaching is a good idea).
I still can't help thinking that there is a better way since ui seems to do it quickly.
Thanks for the help.
-
Numpy would be much faster, if you want to do it pixel wise.
http://stackoverflow.com/questions/384759/pil-and-numpyI'm no PIL expert, but check out the ImagePalette module. You might need to convert to black and white first, or quantize, etc, then it seems like you may be able to directly modify the palette.
Another possibility would be to use ImageMath, but the documentation doesn't seem great there...
-
This works
from scene import * from PIL import Image class MyScene (Scene): def setup(self): img = Image.open('ionicons-arrow-down-c-256').convert('RGBA') red, green, blue, alpha = img.split() img = Image.merge('RGBA', (red, green, alpha, alpha)) self.img = load_pil_image(img) def draw(self): background(1,1,0) image(self.img, 300, 300) run(MyScene())
It's still a bit inefficient. The ionicon is opened as an LA image. I convert it to RGBA because Image.split() does not work with LA images - it would be good if I could extract the alpha without the RGB conversion.