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.
From ui.Image to PIL
-
I have not tried this before. From a ui.Image to a PIL image. I don't understand the differences about the formats. But I can see the PIL module has a wealth of methods/functions like filters for blur etc. unlike ui.Image. I did a pretty good search on the forum and could only find going from PIL Image to ui.Image, not the reverse. I have a bad feeling I am missing something very basic here.
What I am trying to do is load a Pythonista asset like a icon using img = ui.Image.named(IMG_NAME). Once I have that img, I would like to apply some PIL operations on the image. But from what I can see, I need to convert the img to a PIL Image first. This is what I can not work out how to do .To convert it back to a ui.Image should not be a problem as there are quite a few posts on the forum on how to do that.
Any help appreciated -
from PIL import Image, ImageOps, ImageFilter import ui def sketch(img): edge_img = img.filter(ImageFilter.CONTOUR) return ImageOps.grayscale(edge_img) def emboss(img): edge_img = img.filter(ImageFilter.EMBOSS) return ImageOps.grayscale(edge_img) import io def ui2pil(ui_img): png_data = ui_img.to_png() return Image.open(io.BytesIO(png_data)) def pil2ui(pil_image): buffer = io.BytesIO() pil_image.save(buffer, format='PNG') return ui.Image.from_data(buffer.getvalue()) def main(): pilimg = ui.Image.named('Dog_Face') img = ui2pil(pilimg) sketch(img).show() img1 = pil2ui(img) img2 = ui2pil(img1) emboss(img2).show() if __name__ == '__main__': main()
-
Sorry. The variables are wrongly named. "pilimg" should be "img" and "img" should be "pilimg". The program works fine.
-
@abcabc , thanks. It's nice. Exactly what I was after. I understand, this module is going to take quite a bit of thought to optimize both speed and quality. I just never worked with PIL before. Adds an infinite number of ideas what you can do with the built in icons/assets though. I added rotate to your main to test, the result is not great, but I am sure there are a lot of ways to control the quality. But thanks, this gets me up and running so I can play/test
def main(): img = ui2pil(ui.Image.named('iow:arrow_left_a_256')) sketch(img).show() img1 = pil2ui(img) img2 = ui2pil(img1) emboss(img2).show() img3 = img.rotate(45) img3.show()
-
There was this related thread: https://forum.omz-software.com/topic/1935/how-can-i-convert-a-pil-image-to-a-ui-image
I believe that there was once an issue where repeatedly calling a variant of
pil2ui()
that did not closebuffer
resulted in a Pythonista crash. A safer formulation might be:def pil2ui(pil_img): with io.BytesIO() as buffer: pil_img.save(buffer, format='PNG') return ui.Image.from_data(buffer.getvalue()) # other ideas... ========================== import io import ui from PIL import Image, ImageOps, ImageFilter def sketch(pil_img): return ImageOps.grayscale(pil_img.filter(ImageFilter.CONTOUR)) def emboss(pil_img): return ImageOps.grayscale(pil_img.filter(ImageFilter.EMBOSS)) def ui2pil(ui_img): return Image.open(io.BytesIO(ui_img.to_png())) def pil2ui(pil_img): with io.BytesIO() as buffer: pil_img.save(buffer, format='PNG') return ui.Image.from_data(buffer.getvalue()) def main(): img = ui2pil(ui.Image.named('Dog_Face')) sketch(img).show() img1 = pil2ui(img) img2 = ui2pil(img1) emboss(img2).show() if __name__ == '__main__': main()
-
@Phuket2 You can access named images with
Image.open