[Tutorial] Dynamic blur background for overlay menu like iOS

A place for Ren'Py tutorials and reusable Ren'Py code.
Forum rules
Do not post questions here!

This forum is for example code you want to show other people. Ren'Py questions should be asked in the Ren'Py Questions and Announcements forum.
Message
Author
i_jemin
Regular
Posts: 80
Joined: Sat Apr 11, 2015 3:14 pm
Github: i_jemin
Contact:

[Tutorial] Dynamic blur background for overlay menu like iOS

#1 Post by i_jemin »

Ren'Py doesn't support image filters like Gaussian Blur or dynamic filters which immediately adopted to (merged by visible) screen.
Image
Dynamic gaussian blur filter is needed when you wanna making UI like iPhone.

You may make all blurred version of each image including BG, UI, SCG and replace original images when overlay UI is appeared.

At first, I used this method and to make job easier, I wrote function which automatically replace all images on screen to blurred images.
This function is called before Preference Screen(which does not contain background so appeared as overlay menu) is called.
And when Player click Return button on a Preferences Screen, function will be called again, all blurred images being replaced to original images.

But this method require many images and process.

So I make another method which doesn't use pre-proccessed image.

1. Set thumbnail Size.

First, you need to set thumbnail size as your screen size before call overlay menu.

In my case, I wrote function like this.


Code: Select all

#called just right before overlay menu is appeared.
def SetThumbnailFull:
    config.thumbnail_width = config.screen_width
    config.thumbnail_height = config.screen_height

#called just right after overlay menu is disappeared. This function is needed because save file also use thumbnail.
#If you don't call this, you gonna see huge sized thumbnail of your save file on load/save menu.
def SetThumbnailOriginal:
    config.thumbnail_width = ORIGINAL VALUE
    config.thumbnail_height = ORIGINAL VALUE
These function is needed cuz you don't want thumbnail of save file to be huge.
So if you just add resizing code (in my case, it's "size(320,180)") on file_picker screen. You won't need these functions.

Just like this.

Code: Select all

#somewhere on option.rpy file
config.thumbnail_width = config.screen_width
config.thumbnail_height = config.screen_height

Code: Select all

            for i in range(1, 5):
                    # Each file slot is a button.
                button:
                    xmaximum 345
                    ymaximum 220
                    action FileAction(i)
                    add FileScreenshot(i) xoffset 0 yoffset 10 size(320,180)
                    text ( FileTime(i, empty=_("Empty Slot."))) xpos 10 ypos 190 size 20 color '#FFFFFF'

2. Call FileTakeScreenshot() Function when you call preferences screen!

In my case, there is a small button on game screen which call preferences screen.
If I click this button, FileTakeScreenshot function gonna capture current screen.

Code: Select all

##### button on screen which call preferences screen
screen option_button:
    
    imagebutton idle "ui/setting.png" xpos 1130 ypos 0 activate_sound "sfx/basic_click.mp3" action FileTakeScreenshot(), ShowMenu("preferences")
3. Add Captured image as Background at preferences screen and make it blur!

Use FileCurrentScreenshot() function which return captured image right before as a displayable!

Add it to overlay screen as background.

then blur it with transform code.

Code: Select all

screen preferences:
    
        
    tag menu
    
    add FileCurrentScreenshot() at blur
    
    #Other Code~~~~
Code From: http://lemmasoft.renai.us/forums/viewto ... =8&t=10401

Code: Select all

init -1:
    transform blur(child):
        contains:
            child
            alpha 1.0
        contains:
            child
            alpha 0.2 xoffset -3
        contains:
            child
            alpha 0.2 xoffset 3
        contains:
            child
            alpha 0.2 yoffset -3
        contains:
            child
            alpha 0.2 yoffset 3


Image

to

Image

For now, it's not that perfect blur like gaussian blur, but anyway this is basic theory of making overlay UI like iOS.

Now I'm working on adding some image filter function on my game by using third party python lib.

I'm gonna let you know when it's done.

Let me know if you have any questions or better methods.

User avatar
Camille
Eileen-Class Veteran
Posts: 1227
Joined: Sat Apr 23, 2011 2:43 pm
Completed: Please see http://trash.moe
Projects: the head well lost
Organization: L3
Tumblr: narihira
Deviantart: crownwaltz
itch: lore
Contact:

Re: [Tutorial] Dynamic blur background for overlay menu like

#2 Post by Camille »

This is a great idea, thank you for sharing!

User avatar
ChronoWorkS
Newbie
Posts: 16
Joined: Mon Dec 28, 2015 4:58 am
Contact:

Re: [Tutorial] Dynamic blur background for overlay menu like

#3 Post by ChronoWorkS »

I love this, usually it is an elegant way to give focus to certain parts of the game.

User avatar
Hazel-Bun
Eileen-Class Veteran
Posts: 1010
Joined: Sun Oct 28, 2012 6:03 pm
Completed: Sunrise: A Dieselpunk Fantasy & Ultramarine: A Seapunk Adventure
Projects: Thrall: A Dark Otome Visual Novel
Organization: AURELIA LEO, LLC
Tumblr: authorzknight
itch: authorzknight
Contact:

Re: [Tutorial] Dynamic blur background for overlay menu like

#4 Post by Hazel-Bun »

Awesome! Thanks
Black bookstore owner. Diverse fiction reviewer. Bestselling romance author. Award-winning fiction editor. Quite possibly a werewolf, ask me during the next full moon.

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

(Updated Blur)

#5 Post by xela »

i_jemin wrote:or better methods.
Another option:

Code: Select all

init python:
    class Blurred(renpy.Displayable):
        def __init__(self, child, factor=5, **kwargs):
            super(Blurred, self).__init__(**kwargs)

            self.child = renpy.displayable(child)
            self.blurred = None
            self.factor = factor

        def create_blur(self):
            img = self.child
            width, height = get_size(img)
            self.width = width
            self.height = height

            factor = im.Scale(img, width/self.factor, height/self.factor)
            factor = Transform(factor, size=(width, height))

            self.blurred = factor

        def render(self, width, height, st, at):
            if self.blurred is None:
                self.create_blur()

            render = renpy.Render(self.width, self.height)
            render.place(self.blurred)

            return render

        def visit(self):
            return [ self.child ]

image normal_bg = "street.png"
image blurred_bg = Blurred("street.png", factor=3) # default is 5, higher factor means more blur.
Like what we're doing? Support us at:
Image

017Bluefield
Regular
Posts: 93
Joined: Mon Dec 30, 2013 1:55 am
Projects: Project Bluefield - Origins
Organization: Autumn Rain
Deviantart: playerzero17
itch: autumn-rain
Contact:

Re: [Tutorial] Dynamic blur background for overlay menu like iOS

#6 Post by 017Bluefield »

How do you implement that code, exactly? I've gotten an error saying there's no "get_size()".

User avatar
Andredron
Miko-Class Veteran
Posts: 718
Joined: Thu Dec 28, 2017 2:37 pm
Location: Russia
Contact:

Re: [Tutorial] Dynamic blur background for overlay menu like iOS

#7 Post by Andredron »

Code: Select all

init python:
    def get_size(d):
        w, h = renpy.render(renpy.easy.displayable(d), 0, 0, 0, 0).get_size()
        return int(round(w)), int(round(h))
    def show_blur(img, degree = 5):
        w, h = get_size(img)
        factor = im.Scale(renpy.easy_displayable(img), w / degree, h / degree)
        factor = Transform(factor, size = (w, h))
        renpy.show(img, what=factor)

label start:
    show bg1
    pause
    $ show_blur("bg1")
    pause
    return

017Bluefield
Regular
Posts: 93
Joined: Mon Dec 30, 2013 1:55 am
Projects: Project Bluefield - Origins
Organization: Autumn Rain
Deviantart: playerzero17
itch: autumn-rain
Contact:

Re: [Tutorial] Dynamic blur background for overlay menu like iOS

#8 Post by 017Bluefield »

Ah, okay. I'll give that a shot.

017Bluefield
Regular
Posts: 93
Joined: Mon Dec 30, 2013 1:55 am
Projects: Project Bluefield - Origins
Organization: Autumn Rain
Deviantart: playerzero17
itch: autumn-rain
Contact:

Re: [Tutorial] Dynamic blur background for overlay menu like iOS

#9 Post by 017Bluefield »

...hm, no, no effect. No error screen, either, though.

User avatar
Andredron
Miko-Class Veteran
Posts: 718
Joined: Thu Dec 28, 2017 2:37 pm
Location: Russia
Contact:

Re: [Tutorial] Dynamic blur background for overlay menu like iOS

#10 Post by Andredron »

017Bluefield wrote: Sat Sep 01, 2018 12:27 am ...hm, no, no effect. No error screen, either, though.
No def
Image

Yes def
Image

User avatar
xela
Lemma-Class Veteran
Posts: 2481
Joined: Sun Sep 18, 2011 10:13 am
Contact:

Re: [Tutorial] Dynamic blur background for overlay menu like iOS

#11 Post by xela »

Sorry, didn't test before posting...

Code: Select all

init python:
    def get_size(d):
        d = renpy.easy.displayable(d)
        w, h = d.render(0, 0, 0, 0).get_size()
        return int(round(w)), int(round(h))
    
    class Blurred(renpy.Displayable):
        def __init__(self, child, factor=5, **kwargs):
            super(Blurred, self).__init__(**kwargs)

            self.child = renpy.displayable(child)
            self.blurred = None
            self.factor = factor

        def create_blur(self):
            img = self.child
            width, height = get_size(img)
            self.width = width
            self.height = height

            factor = im.Scale(img, width/self.factor, height/self.factor)
            factor = Transform(factor, size=(width, height))

            self.blurred = factor

        def render(self, width, height, st, at):
            if self.blurred is None:
                self.create_blur()

            render = renpy.Render(self.width, self.height)
            render.place(self.blurred)

            return render

        def visit(self):
            return [ self.child ]

image bg normal = "cafe.jpg"
image bg blurred = Blurred("cafe.jpg", factor=3)
image bg very_blurred = Blurred("cafe.jpg", factor=10)

label start:
    show bg normal
    pause
    show bg blurred
    pause
    show bg very_blurred
    pause
Like what we're doing? Support us at:
Image

017Bluefield
Regular
Posts: 93
Joined: Mon Dec 30, 2013 1:55 am
Projects: Project Bluefield - Origins
Organization: Autumn Rain
Deviantart: playerzero17
itch: autumn-rain
Contact:

Re: [Tutorial] Dynamic blur background for overlay menu like iOS

#12 Post by 017Bluefield »

Okay, that works! But...is there a way to render the blur *and* keep the alpha to 1.0? The render I get shows the checkerboard pattern.

User avatar
AERenoir
Veteran
Posts: 320
Joined: Fri May 27, 2011 8:23 pm
Contact:

Re: [Tutorial] Dynamic blur background for overlay menu like iOS

#13 Post by AERenoir »

Apparently this tutorial doesn't work on Ren'py 7.1. The screenshot doesn't get attached to the menu screen properly. It just ended up being blank.
Still works on 6.99.14 though. Any idea what needs to be fixed for 7.1? Or should I just keep using 6.99.14?

philat
Eileen-Class Veteran
Posts: 1909
Joined: Wed Dec 04, 2013 12:33 pm
Contact:

Re: [Tutorial] Dynamic blur background for overlay menu like iOS

#14 Post by philat »

It works fine for me.

017Bluefield
Regular
Posts: 93
Joined: Mon Dec 30, 2013 1:55 am
Projects: Project Bluefield - Origins
Organization: Autumn Rain
Deviantart: playerzero17
itch: autumn-rain
Contact:

Re: [Tutorial] Dynamic blur background for overlay menu like iOS

#15 Post by 017Bluefield »

Yeah, same here. Granted, it still has that opacity problem (for me, anyway).

Post Reply

Who is online

Users browsing this forum: No registered users