Just as a final follow-up: Using appex.get_attachments and Image.named works perfectly. Here my workflow:
I get the image file names via appex.get_attachments.
I weed out the paths for heic files which have a accompaning other image file.
Finally I load the remaining images manually via the Image.named method.
Traceback (most recent call last):
File "/private/var/mobile/Containers/Shared/AppGroup/4696D4C5-8877-4DAB-9679-C1C82C4A5C18/Pythonista3/Documents/CompletedPrograms/ImageMatching.py", line 412, in <module>
File "/private/var/mobile/Containers/Shared/AppGroup/4696D4C5-8877-4DAB-9679-C1C82C4A5C18/Pythonista3/Documents/CompletedPrograms/ImageMatching.py", line 278, in matchImage
File "/var/containers/Bundle/Application/24BCA42A-E70C-42BD-BD39-68CECBB90922/Pythonista3.app/Frameworks/Py3Kit.framework/pylib/site-packages/PIL/ImageChops.py", line 138, in screen
ValueError: images do not match
@ccc I will post something in a few days when I clean some things up. I created an endless loop calling a function that wrote a large amount of data to a BytesIO. No crash. I downloaded objgraph, and this never showed any increase in BytesIO objects.
My attempt at writing an image viewer that uses pil2ui failed after 4 photos (with or without del bIO) because of apparently a bad image in my photos (at least one that PIL choked on). I will say that, in the case of displaying photos assets, one should be using .get_ui_image instead of .get_image. That avoids any round trip through PIL, which is probably where any leaks or bugs occur. A simple image viewer using get_ui_image ran for longer than I cared to wait without a crash.
Creating ui.Images also requires some care, because these might not get gc'd automatically. I believe the best practice is to include a with objc_util.autoreleasepool(): when many UIImages are created -- though I haven't had time to explore whether setting the imageview image causes the old image to get leaked (in which case it would be necessary to manually handle the deallocation of the UIImage object)