Forum Archive

Button image from URL

Kipekeedev

Hello again. I recently received some great help on how to a group of url images to a view. It works perfectly.

Here's the code

import feedparser, ui, Image, requests
from urllib2 import urlopen
from io import BytesIO

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]

class AlbumView(ui.View):
    def __init__(self, image_urls):
        #self.present()
        for i, url in enumerate(image_urls):
            #new code
            img = Image.open(BytesIO(urlopen(url)).read())
            button.ui.Button()
            button.image = img

            #old code
            '''
            image_view = ui.ImageView()
            image_view.load_from_url(url)
            self.add_subview(image_view)
            image_view.x = (i % 5) * 128 + 10
            image_view.y = (i / 5) * 128 + 10
            '''
AlbumView(get_image_urls(url))

But what I want to do is instead of a plain image I want each URL image to be a button. ( the url image is used as the button image).

I used BytesIO but I get an error that it's returning an instance not an ImageI'm having a hard time converting to url image to a ui.Image , which the button image field takes.

Thanks

Webmaster4o

You have to download the image. Try

i=urllib2.urlopen(image_url)
b = io.BytesIO(i.read())

for putting data into a BytesIO

Kipekeedev

@Webmaster4o

Yes and it gives me and error that the value needs to be a ui.Image


# example url
url = 'http://is4.mzstatic.com/image/thumb/Music7/v4/53/fc/a2/53fca253-84b1-f2cd-4e17-98be502ec53c/UMG_cvrart_00602547534873_01_RGB72_1500x1500_15UMGIM41882.jpg/55x55bb-85.jpg'

i = urlopen(url)
b= BytesIO(i.read())
img = Image.open(b)
btn = ui.Button()
btn.image  = img         #<<< TypeError: Expected a ui.Image
omz

Try something like:

img_data = urlopen(url).read()
img = ui.Image.from_data(img_data)
# ...
Kipekeedev

@omz

So simple. But worked perfectly. Thanks

Webmaster4o

Thanks. I couldn't test that code when I wrote it,

ccc

I had to use button.background_image... https://github.com/cclauss/Pythonista_ui/blob/master/TopTenView.py

omz

@ccc That shouldn't be necessary, and you'll lose touch highlighting this way. You can use the with_rendering_mode method to make opaque/colored images usable as button images:

# ...
img = ui.Image.from_data(requests.get(url).content)
img = img.with_rendering_mode(ui.RENDERING_MODE_ORIGINAL)
button.background_image = img
# ...
ccc

Ahhh. Yes. I forgot that trick.

Suggested API improvement: ui.ImageView has a slick .load_from_url() method. Would it be possible to give ui.Button a similar method which would be equivelent to button.image = ui.Image.from_data(requests.get(url).content).with_rendering_mode(ui.RENDERING_MODE_ORIGINAL) which can be a bit cumbersome to type?

ccc

Also, why is it advantageous to have the default rendering mode be something different than ui.RENDERING_MODE_ORIGINAL?

omz

Also, why is it advantageous to have the default rendering mode be something different than ui.RENDERING_MODE_ORIGINAL?

If you use typical "glyph" button icons (with transparency), you'd end up with black&white images, and the button would ignore its tint_color. Buttons (and a couple of other UI elements) only use their tint color when the image has a rendering mode of either RENDERING_MODE_TEMPLATE or RENDERING_MODE_AUTOMATIC (the default).