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.
How to debug crash of image script when it's called as extension
-
@halloleooo, you could explicitly write lines to a file at different points of your script, starting with a version that does nothing much, before adding the image handling.
pathlib.Path.write_text
is a convenient one-liner for this. -
@halloleooo I sometimes noticed, in appex mode, that an error was lodged in the console but was hidden by a ui.view. By closing the view, without terminating the program, there was a way to see the log.
-
@mikael @cvp Thanks for the suggestions. I will try them.
My own investigation shows, the issue seems to be related to memory use of the images. Not really big stuff, but the size seems to be the culprit:
- When I use 2 images with 1MB each it crashes.
- When I use 2 images with 10Kb each it works.
All 4 images come from the Files app.
-
@halloleooo, from what I read, share extensions should have a 120 MB memory limit, not sure how much Pythonista takes.
-
@mikael Mmmh, interesting. So why does my share extension crashes with (mere) 1MB images???
-
@halloleooo advice: if you want to join photos, don't run in appex mode and use photos module to pick two images. We always have had memory problems with big photos in appex mode.
-
@halloleooo I think that a pil image of 10000x10000 pixels uses 10000x10000x4 bytes = 400 MB
even if your compressed jpeg is a 6MB file -
@cvp Aha! that makes total sense!
But how can I not run in
appex
mode, but still join images from anywhere? I thought that's what share extensions are for... -
@halloleooo perhaps find a way without passing via pil, for example, via ui.image_context?
-
@halloleooo if you want a join of original pictures, I think that even ui.image_context will use a lot of memory, but if you want a smaller jointed image, it could be possible to work with resized images.
-
@halloleooo please, try this one in the share sheet
import appex import ui import io from PIL import Image def pil2ui(imgIn): with io.BytesIO() as bIO: imgIn.save(bIO, 'PNG') imgOut = ui.Image.from_data(bIO.getvalue()) del bIO return imgOut ui_images = [] # assume two images are shared files = appex.get_attachments() for f in files: pil = Image.open(f)#,mode='r') ui_image = pil2ui(pil) del pil w,h = ui_image.size wi = 400 hi = wi*h/w with ui.ImageContext(wi,hi) as ctx: ui_image.draw(0,0,wi,hi) del ui_image ui_resize = ctx.get_image() ui_images.append(ui_resize) del ui_resize w1,h1 = ui_images[0].size w2,h2 = ui_images[1].size # assume images have same height with ui.ImageContext(w1+w2,h1) as ctx: ui_images[0].draw(0,0,w1,h1) ui_images[1].draw(w1,0,w2,h2) ui_image_joined = ctx.get_image() w,h = ui_image_joined.size v = ui.ImageView() v.frame = (0,0,400,400*h/w) v.content_mode = ui.CONTENT_SCALE_ASPECT_FIT v.image = ui_image_joined v.present('')
-
@cvp Thanks for the detailed script.
One thing I am wondering about is: You get the images from the share extension as PIL images via
appex.get_attachments()
and then convert them to UI images. Isn't there a way to get them directly as UI images? I thought UI image is the iOS-native format...
-
@halloleooo you're right but we got some problems with images in appex mode, thus...
Else, I use this where you can set type you wantimg = appex.get_image(image_type='pil')
-
Doesn't appex provide a
get_ui_image
function? That will be much lighter weight than going through PIL and back. -
@JonB sure, he knows that, but in the past, we got some problems with it.
Édit: believe me, if we go through pil, it is not for the pleasure to do it.
-
@cvp So what are the problems with
get_ui_image
? -
Correction: appex does not have a get_ui_image
-
We mixed with asset.get_ui_image
-
I have been disturbed only because the post comes from @JonB
-
@halloleooo doc dixit, you could try with
img = appex.get_image(image_type='ui')
#files = appex.get_attachments() #for f in files: files = appex.get_images(image_type='ui') for ui_image in files: #pil = Image.open(f)#,mode='r') #ui_image = pil2ui(pil) #del pil