Forum Archive

Multiple image tiles

Kipekeedev

Hello. I'm new to Pythonista. I'm working on a simple app that request data from a music api. What I want to do on my main view is show the image of the top 10 albums. I don't know how to implement this onto a view. My json data for the image uses a url. Is there a method that I can use to pass in the url the show the image? Can someone please give me a simple example of how to do this.

ccc

Can you please provide us with a URL that has an image? Do you want to use ui, scene, or canvas to build your app?

Webmaster4o

Say you have the urls in a list. You can download them into a list like so:

import requests, io, Image
#urls should be a list of urls from which you want to retrieve images
images = [Image.open(io.BytesIO(requests.get(url).content)) for url in urls]

now you have a list of images, called images. You can put them into a UI by using ImageViews. I've written a script, found here that can display a nice UI for presenting images. If you download this and move it into site-packages, you can present your images as simply as

from CoverFlow import CoverFlow
CoverFlow(images).present()

Now you have all your images presented in a format you can swipe through. If you want to use this in conjunction with other UI elements, you can, just look at the documentation for ui, and treat CoverFlow as you would any other UI element.

dgelessus

@Webmaster4o If you want to get the data of a binary Requests response, use response.content, not response.text. The first one is guaranteed to be the raw byte data (str in Python 2, bytes in Python 3), and the second one may have been incorrectly decoded as if it were text.

ccc

Opening BytesIO without closing them can cause you to leaka lot of memory.

See: https://forum.omz-software.com/topic/1457/camera-to-dropbox/7

Webmaster4o

This seems to imply that it might be otherwise, does Pythonista have a garbage collector?

ccc

The answer that you site does mention the preferred way which is what I advocated. Try cycling thru a long list of large images and see if problems emerge.

Pythonista is an implementation of cPython so it does indeed have a garbage collector. However Apple only allows iOS apps to have a single thread of execution (still true in iOS9?) so Python instances tend run longer in Pythonista than they would on your Mac or PC. On those other platforms garbage collection is less disruptive because it can be done in a separate thread of execution. This means that GC is run less often in Pythonista makes it more sensitive to unclosed resources than other platforms. Images can take up a lot of memory compounds the issue.

JonB

pythonista uses ref counting, so no close is needed. here is a way to check, using weakref handlers:

# coding: utf-8
import io, weakref

def handler(ref):
    print 'buffer closed'

def f():
    buffer = io.BytesIO()
    ref = weakref.ref(buffer, handler)
    buffer.write('something')
    return buffer.getvalue()

for i in xrange(5):
   print 'before'
   f()
   print 'after'

as an aside, i think ios does allow threads, just not multiple processes.

MartinPacker

@Webmaster4o Note: Garbage Collection (GC) is not a universal panacea. If, for example, you hang on to objects or handles you might (inadvertently) defeat GC.

And I like @ccc's response on GC pragmatics.

Pedagogical point: GC schemes are a big factor in (languages like) java's performance. They've evolved over the years.

Kipekeedev

@ccc the url is

https://itunes.apple.com/us/rss/topsongs/limit=10/json

And I'm requesting the "im:image" url

Kipekeedev

@Webmaster4o sounds great. I'll try this ASAP. Also what if I didn't want a cover flow, I was thinking more of a table of images.

Kipekeedev

@ccc i would this the ui module would be more appropriate. Isn't scene and canvas more for a game interface?

ccc

Part I: Get the image URLs for the Top 10 iTunes songs:

import feedparser

url = 'https://itunes.apple.com/us/rss/topsongs/limit=10/xml'

def get_image_urls(itunes_url):
    for entry in feedparser.parse(itunes_url).entries:
         yield entry['summary'].partition('src="')[2].partition('"')[0]

print('\n'.join(get_image_urls(url)))
ccc

Part II: Adds a ui.View... https://github.com/cclauss/Pythonista_ui/blob/master/TopTenView.py

Kipekeedev

@ccc wow! I didn't know it was so simple. Thanks for the sample code!!

Kipekeedev

@ccc one question. Where did you get the number 128 in the image_view.x and y?

Webmaster4o

It has to do with the spacing between the pictures. Try adjusting the value and seeing what happens.

Kipekeedev

@Webmaster4o can you give me a full example of your suggestion above. I keep getting an error.