How to set the image of an ImageView to an image from Pillow?
imageproperty, but it is of type
ui.Image, not of type
What can I do? How do I convert
Thanks heaps for any pointers!
import io def pil2ui(imgIn): with io.BytesIO() as bIO: imgIn.save(bIO, 'PNG') imgOut = ui.Image.from_data(bIO.getvalue()) #del bIO return imgOut ui_image = pil2ui(pil_image)
@cvp, curious about the
del bIO, what is it for?
@cvp, very cool! Works perfectly. Thanks a lot!
bIOso you do not need to call
bIO.close()but closing a file (in this case, an in-memory file) does not force the garbage collector to deallocate the memory.
del bIOis a strong suggestion to the garbage collector to deallocate the memory. If you are only picking one file, then you should have no worries. However, if you process many large image/movie files one-after-another in Pythonista, you might find that calling
delwill prevent out-of-memory crashes.
@ccc thanks a lot. Sincerely, I like to get clear explanations of technical matters.
Hmm, not sure I agree.
bIO is defined within the scope of the function def. When the function returns, bIO falls out of scope. As we have created no other references to bIO, it's reference count should then be 0 and it should then be immediately deallocated.
Does defining bIO in a context manager create a reference cycle? I don't think so.
The context manager probably has a reference to bIO, but bIO doesn't have a reference to the context manager. As long as we don't create a reference cycle, the periodic gc is not needed to resolve . It might be different if you had this within a for loop, instead of a function (though I don't think so).
I suppose it would be easy to use something like the objgraph module to check either way.
the garbage collector reminds me of the days of basic on Tandy Trs80. Afterwards, I developed a lot on ibm mainframe and unix, in languages where you didn't have to think so much about memory problems. but it is true that in Pythonista, this kind of limitation often crashes my scripts which handle a lot of images.
@JonB Try to create a picture frame app and see if Pythonista can cycle thru the 50 most recent pictures in Photos without
deland without crashing.
@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
photosassets, one should be using
.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_imageran 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)