Proportional scale function

In this forum we discuss the future of Ren'Py, both bug fixes and longer-term development. Pre-releases are announced and discussed here.
Post Reply
Message
Author
Cironian
Regular
Posts: 33
Joined: Sun Aug 26, 2007 5:34 pm
Projects: Dragon Story
Contact:

Proportional scale function

#1 Post by Cironian »

Here's something that I came up with in my development due to general laziness. ;-)

Consider it a mix between im.Scale and im.FactorScale for character images. The purpose is to get something useful on the screen for when you don't yet have the final artwork for your VN and thus don't want to manually scale your sketches or other placeholders to the proper size. This class takes an image file, maximum width and maximum height as parameters and then makes the image fit into the provided parameters by proportional downscaling. The logic is ripped from the builtin im.Scale function, so it supports lazy loading of the image.

I couldn't think of a way to do this with the builtin functions, since you need the original image dimensions to do proportional scaling to a constraint box, and while there is renpy.image_size, that would require loading all the images on startup.

You can use it basically like the builtin scalers with a call like:

Code: Select all

    image jessica neutral = ProportionalScale("red0.jpg", 550, 300)
The code itself:

Code: Select all

init:
    python:
        class ProportionalScale(im.ImageBase):
            def __init__(self, imgname, maxwidth, maxheight, bilinear=True, **properties):
                img = im.image(imgname)
                super(ProportionalScale, self).__init__(img, maxwidth, maxheight, bilinear, **properties)
                self.imgname = imgname
                self.image = img
                self.maxwidth = int(maxwidth)
                self.maxheight = int(maxheight)
                self.bilinear = bilinear

            def load(self):
                child = im.cache.get(self.image)
                currentwidth, currentheight = child.get_size()
                xscale = 1.0
                yscale = 1.0
                if (currentwidth > self.maxwidth):
                    xscale = float(self.maxwidth) / float(currentwidth)
                if (currentheight > self.maxheight):
                    yscale = float(self.maxheight) / float(currentheight)
                if (xscale < yscale):
                    minscale = xscale
                else:
                    minscale = yscale
                newwidth = currentwidth * minscale
                newheight = currentheight * minscale
                #Debug code to see when the loading really happens
                #renpy.log("Loading image %s from %f x %f to %f x %f" % (self.imgname, currentwidth , currentheight , newwidth, newheight))
        
                if self.bilinear:
                    try:
                        renpy.display.render.blit_lock.acquire()
                        rv = renpy.display.scale.smoothscale(child, (newwidth, newheight))
                    finally:
                        renpy.display.render.blit_lock.release()
                else:
                    try:
                        renpy.display.render.blit_lock.acquire()
                        rv = renpy.display.pgrender.transform_scale(child, (newwidth, newheight))
                    finally:
                        renpy.display.render.blit_lock.release()
                return rv

            def predict_files(self):
                return self.image.predict_files()
Let me know if this is useful for you!

User avatar
jack_norton
Lemma-Class Veteran
Posts: 4085
Joined: Mon Jul 21, 2008 5:41 pm
Completed: Too many! See my homepage
Projects: A lot! See www.winterwolves.com
Tumblr: winterwolvesgames
Contact:

Re: Proportional scale function

#2 Post by jack_norton »

Just used this in my game Planet Stronghold! Thanks, was very useful :)
follow me on Image Image Image
computer games

User avatar
DarrylDidIt
Newbie
Posts: 14
Joined: Sat Jul 09, 2016 5:35 pm
Contact:

Re: Proportional scale function

#3 Post by DarrylDidIt »

This is immensely useful/under appreciated! Great work.

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

Re: Proportional scale function

#4 Post by xela »

Yeap, it should be called ProportionalDownScale... Prop scale I use is a small rewrite along the lines of:

Code: Select all

init python:
    class ProportionalScale(im.ImageBase):
        def __init__(self, imgname, maxwidth, maxheight, bilinear=True, **properties):
            img = im.image(imgname)
            super(ProportionalScale, self).__init__(img, maxwidth, maxheight, bilinear, **properties)
            self.imgname = imgname
            self.image = img
            self.maxwidth = maxwidth
            self.maxheight = maxheight
            self.bilinear = bilinear

        def load(self):
            surf = im.cache.get(self.image)
            width, height = surf.get_size()
            
            ratio = min(self.maxwidth/float(width), self.maxheight/float(height))
            width = int(round(ratio * width))
            height = int(round(ratio * height))
            
            if self.bilinear:
                try:
                    renpy.display.render.blit_lock.acquire()
                    rv = renpy.display.scale.smoothscale(surf, (width, height))
                finally:
                    renpy.display.render.blit_lock.release()
            else:
                try:
                    renpy.display.render.blit_lock.acquire()
                    rv = renpy.display.pgrender.transform_scale(surf, (width, height))
                finally:
                    renpy.display.render.blit_lock.release()
            return rv

        def predict_files(self):
            return self.image.predict_files()
which should scale both up and down.
Like what we're doing? Support us at:
Image

Post Reply

Who is online

Users browsing this forum: No registered users