WindowXML - PIL Image
#1
Hello, I hope I am in the right forum (wasn't sure if it is a skinning or addon related problem).
I am working on an addon to control my Mopidy Server (with spotipy integration) and made a GUI with WindowXML:

Image

I'd like to set the background to a blurred version of the cover. I figured out how to blur an image with PIL, save to the disc and set it as the background, but the performance is not ideal.
Is it possible to directly set the PIL image as an Image Control, thus eliminating the need to save it locally?
Reply
#2
I am not aware of a way to not use a direct path, as far as images go, I have an entire ui that uses PILl for everything and see no performance hit. What is your final image size/format/quality. . I would a suggest just using an affect on the image control to make it looks blurred, if one does not exist that meets your needs, then make make a transparent png that is just a blurred overlay and put it on top of your image control. But in reality you shouldn't be seeing much of a performance issue from oil unless you are saving in to high of a quality. If I may be honest. Having a blurred cover art behind a non blurred cover would not be something I would want to see in an app I use, that is just my opinion though.

The ui you have there looks nice as is. If that is a blurred cover then you have the image extremely large because that would only be about an inch x inch square of that cover which means that image has to be in the large MB range of I had to guess.

A mirror effect under that cover might look nice though, but would have to see to know for sure.
Reply
#3
Thanks for the answer,
I no longer think it is a performance issue, rather than a programming issue after all and I don' get to figure out what's wrong.
How do i properly get the image to refresh, even though the path stays the same? I guess it is a cache problem or whatever

I will definitely think about your idea with the mirrored image, but I want to test this out first and see how it looks (i want a really really blurred version of the cover, to the point that essentially only the color and a bit of texture is left, currently I am using a gaussian radius of 80.. the spotify app on iOS is basically doing the same )
Reply
#4
If you want an image to refresh that uses the same file name or url you have to call setimage and pass the location and I think False to say no cache. The documentation for setImage should tell you which is True and which is false.


There is a real spotify addon out there. But lacks features. Not spotmc but actually spotify. Is yours going to be dedicated to spotify or support multiple sources?
Reply
#5
Hmmm I don't get it to work.. here's the function, that tries to set the image (it's the same function that sets the cover. I just used it, because it was already there):

Code:
def setCover(self):
        self.cover_old = self.cover
        self.cover = spotify.album(client.currentsong()['x-albumuri'])['images'][0]['url']
        if self.cover != self.cover_old:
            self.blurCover()
            self.win.setProperty('cover', self.cover)
            self.background.setImage(os.path.join(addonpath, 'bg.jpg'), useCache = False)
        else: pass

and that's the function that blurres the image:

Code:
def blurCover(self):
        cover_url = urllib.urlopen(spotify.album(client.currentsong()['x-albumuri'])['images'][0]['url'])
        bg_image = io.BytesIO(cover_url.read())
        cover = Image.open(bg_image)
        bg = cover.filter(ImageFilter.GaussianBlur(80))
        bg.save(os.path.join(addonpath, 'bg.jpg'))

that's the control:

Code:
        <control type="image" id="1001">
            <description></description>
            <left>0</left>
            <top>0</top>
            <width>1920</width>
            <height>1080</height>
            <visible>true</visible>
            <!-- <texture>background.png</texture> -->
        </control>

the cover gets updated, but the Background not and I have no idea why..
BTW the blurred image is saved just fine and like instantly.


The addon is in a really really early state. Right now it just displays and controls the current playlist (and spotify is only used to grab the cover, but you could use mpd just as well)
I think I know the addon you are speaking of and I just don't like it. And the Problem is, it doesn't really do what I want it to do. I want to control the same music output from all of my devices and the Kodi webinterface ist not really suitable for controlling a music addon. Iris (a mopidy webserver) on the other hand does the job beautifully. Sooo I thought I start developing Kodi addons and here I am Big Grin
Reply
#6
Do you have any errors in the log?
Are you sure it is making it I to the if statement and not going to the else?
I would try hard coding an image url to see if that set's as the background.
I've encountered issues where it tries to use a corrupt cache file even know you say not to cache
Reply
#7
no, no errors and yes it makes it to the if statement, because the image gets blured and saved and the albumcover (the other image control) get's changed (but that one always gets a new url)

What's strange as well is, that the image is changed either if I restart kodi or if I wait a couple of min before I reopen the addon but never while running, so it is basically screaming cache. I tried to delete the cache entirely but the problem persists. The log also doesn't say that the file was cached (in contrary to the album art it grabs from the spotify servers for the other image control)

maybe I will just give unique names..
Reply
#8
Okay, so giving unique names made the trick. But naturally now I have to delete the files afterwards.
Is there a better way than creating a folder, writing the images into the folder and deleting the whole folder, when the addon stops?

is there a way of animating an imagechange?

BTW I really like the looks of it:

Image
Image
Reply
#9
(2017-01-12, 21:36)Halbstark Wrote: the cover gets updated, but the Background not and I have no idea why..

i don't think kodi will pick up the new image, unless the path changes.

to test if my assumption is correct, try this:
Code:
self.background.setImage('')
xbmc.sleep(100)
self.background.setImage(os.path.join(addonpath, 'bg.jpg'), useCache = False)

the easiest way would indeed be to use unique paths.

i like the effect btw. :-)
Do not PM or e-mail Team-Kodi members directly asking for support.
Always read the Forum rules, Kodi online-manual, FAQ, Help and Search the forum before posting.
Reply
#10
perhaps it's time for an invalidateImageCacheEntry binding.
Reply
#11
Thank you Smile

I've read that with the path change somewhere and tried to set it to an empty path but didn't think about that sleeping part so it did not work.
I've implemented the thing with the unique paths and it works, but I need to work out a way to synchronize both changes or at least (or maybe for better) implement some sort of animation.
Reply
#12
that might prove to be a bit difficult, since creating the blurred image takes 'some' time.

you could define a fadetime for both image controls in your xml.
if you use a long fadetime for the cover and a relatively short time for the background, it may mask things a bit,
but i doubt there's a way to get it 100% perfect.
Do not PM or e-mail Team-Kodi members directly asking for support.
Always read the Forum rules, Kodi online-manual, FAQ, Help and Search the forum before posting.
Reply
#13
(2017-01-13, 14:58)Halbstark Wrote: Thank you Smile

I've read that with the path change somewhere and tried to set it to an empty path but didn't think about that sleeping part so it did not work.
I've implemented the thing with the unique paths and it works, but I need to work out a way to synchronize both changes or at least (or maybe for better) implement some sort of animation.

No an empty path will not work. I have seen this issue even when changing to another file and then back with locally stored images. I have tried tricks like sleep, del file and recreate, changing the file path multiple times in a row, refreshing the container and so on with no luck. Changing the file name should not be that big of an issue.

Just use an incrementing counter and right before you create your file. Set a variable as the file name + counter and run a delete on it and then increment the counter and set that variable to the same file name + counter again. Even if a user exits you should never have more than a total of 2 files.

bgimg = 'bg%s.jpg' % ctr

Then do your join and del

ctr +=1

And so on. It is a crude solution but it would always provide a new image path.


Since my entire UI uses PIL I personally do not delete the files. I just save them so they do not need to be recreated again and provide the user the option to delete them. As long as you are not saving them with a large format it should not be too much of an issue.

That being said I am no expert. Ronie is the guru Smile
Reply
#14
I've solved it like this:

Code:
def blurCover(self):
        self.cover_url = spotify.album(client.currentsong()['x-albumuri'])['images'][0]['url']
        self.cover_urllib = urllib.urlopen(spotify.album(client.currentsong()['x-albumuri'])['images'][0]['url'])
        self.bg_image = io.BytesIO(self.cover_urllib.read())
        self.bg_uf = Image.open(self.bg_image)
        self.bg = self.bg_uf.filter(ImageFilter.GaussianBlur(80))
        self.bg = self.bg.point(lambda p: p*0.5)
        self.bgpath = os.path.join(backgrounds, self.cover_url.rsplit('/', 1)[-1]+'.jpg')
        self.bg.save(os.path.join(addonpath, self.bgpath))
        return self.bgpath

so the image is named like it is on the server, that should definitely be unique

and I just create the folder at the beginning of the script with:
Code:
if not os.path.exists(backgrounds):
    os.makedirs(backgrounds)

and delete it with:

Code:
shutil.rmtree(os.path.join(backgrounds))

thats working perfectly for me, but I could indeed just save them (they have typically around 8 KB), so they do not have to be loaded and filtered again.
Reply
#15
(2017-01-13, 16:03)Protocol-X Wrote: That being said I am no expert. Ronie is the guru Smile

pff... the only guru in this thread is ironic_monkey ;-)
Do not PM or e-mail Team-Kodi members directly asking for support.
Always read the Forum rules, Kodi online-manual, FAQ, Help and Search the forum before posting.
Reply

Logout Mark Read Team Forum Stats Members Help
WindowXML - PIL Image0