save cropped screeshot [solved]

Discuss how to use the Ren'Py engine to create visual novels and story-based games. New releases are announced in this section.
Forum rules
This is the right place for Ren'Py help. Please ask one question per thread, use a descriptive subject like 'NotFound error in option.rpy' , and include all the relevant information - especially any relevant code and traceback messages. Use the code tag to format scripts.
Post Reply
Message
Author
User avatar
Kia
Eileen-Class Veteran
Posts: 1040
Joined: Fri Aug 01, 2014 7:49 am
Deviantart: KiaAzad
Discord: Kia#6810
Contact:

save cropped screeshot [solved]

#1 Post by Kia »

I've been trying to figure out how to take a screenshot and crop it before saving it. but it's not going as I imagined. since I'm out of ideas, here's what I've tried, please let me know if there's something I'm missing or doing wrong.

Code: Select all

renpy.screenshot(filename)
seems to return False every time and

Code: Select all

renpy.game.interface.save_screenshot(filename)
Doesn't seem to work either

Code: Select all

renpy.take_screenshot((1920,1080))
photo = renpy.game.interface.get_screenshot()
works and I can crop it too, but I have no idea how to save a crop

I've rummaged through the renpy files, found (line 2542 in core.rpy):

Code: Select all

save_screenshot(self, filename)
and (line 71 scale.py):

Code: Select all

image_save_unscaled(surf, filename)
Those two functions seem like what I need, but they add `surf` to my pile of unexplained terms that I can't figure out

The closest thing I've found is this post from nine years ago that works perfectly, just have to figure out how to crop the image the way it can be written.
Last edited by Kia on Sun May 02, 2021 1:53 am, edited 1 time in total.

User avatar
mavyxdawn
Regular
Posts: 72
Joined: Sun Dec 20, 2015 6:18 pm
Github: mavyxdawn
itch: zeillearnings
Discord: _zeil
Contact:

Re: save cropped screeshot

#2 Post by mavyxdawn »

have you tried screenshot_crop?

Once you attempt to screenshot, it will take the size defined here ^
YouTube: Zeil Learnings
itch.io: Zeil Learnings

Image

User avatar
Kia
Eileen-Class Veteran
Posts: 1040
Joined: Fri Aug 01, 2014 7:49 am
Deviantart: KiaAzad
Discord: Kia#6810
Contact:

Re: save cropped screeshot

#3 Post by Kia »

mavyxdawn wrote: Sun Apr 25, 2021 9:06 pm have you tried screenshot_crop?
I did, but I'm trying to take the screenshot in a python function where I calculate the crop every time, give it my own name and save it to the destination I'm giving it. To use that one, I need to make `renpy.screenshot(filename)` work and it just returns False.

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2400
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: save cropped screeshot

#4 Post by Ocelot »

Did you try to set confog.febug to True, to force an exception in case someting goes wrong in your attemts to see what is going wrong. It could be anything from absolute vs relative paths to access rights.
< < insert Rick Cook quote here > >

User avatar
Kia
Eileen-Class Veteran
Posts: 1040
Joined: Fri Aug 01, 2014 7:49 am
Deviantart: KiaAzad
Discord: Kia#6810
Contact:

Re: save cropped screeshot

#5 Post by Kia »

oh, you mean debug, looks like you've typed it in a hurry. I'll try it, thank you

User avatar
Kia
Eileen-Class Veteran
Posts: 1040
Joined: Fri Aug 01, 2014 7:49 am
Deviantart: KiaAzad
Discord: Kia#6810
Contact:

Re: save cropped screeshot

#6 Post by Kia »

well, I've use config.debug and managed to get the save screen work (I was missing the file extension)
but the more I dig, the harder it gets.
now I need to figure out how to pass

Code: Select all

        renpy.take_screenshot((1920,1080))
        photo = renpy.game.interface.get_screenshot()
to

Code: Select all

renpy.display.scale.image_save_unscaled(window, filename)
or what object do I need to pass to

Code: Select all

        surftree = renpy.display.render.render_screen(
            ????,
            renpy.config.screen_width,
            renpy.config.screen_height,
            )
to construct a surftree to save

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2400
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: save cropped screeshot

#7 Post by Ocelot »

Did you manage to get renpy.screenshot work? You can then just set config.screenshot_crop to whatever you want and then restore it to the previous value.
< < insert Rick Cook quote here > >

User avatar
Kia
Eileen-Class Veteran
Posts: 1040
Joined: Fri Aug 01, 2014 7:49 am
Deviantart: KiaAzad
Discord: Kia#6810
Contact:

Re: save cropped screeshot

#8 Post by Kia »

I did that, there is one problem with using renpy.screenshot out of the box. it screenshots at the current window size and messes up the cropping, that's why I'm looking deeper into it's function and trying to figure out how to capture the screen at the original size instead.
since renpy.screenshot is the short format for renpy.game.interface.save_screenshot and I've found the function inside core.rpy I can copy that function if I can figure how to make a surftree, however, I have no idea what kind of object I have to pass to renpy.display.render.render_screen to create one

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2400
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: save cropped screeshot

#9 Post by Ocelot »

It appears that it is PyGame surface. I didn't dare to explore further to figure out what RenPy expects it to contain. However, you can just reuse data that is already there. Just copy method, change it as you want, and either dynamically patch it into Interface class or simply pass it as first argument to the new function.

Example:

Code: Select all

class A:
    foo(self, other):
        self.something = other

# 1st approach:
def bar(self, other, another):
    self.something = other * another

setattr(A, 'bar', bar)
x = A()
x.bar(1, 2)

# 2nd approach
def baz(self, other, another):
    self.something = other * another

y = A()
baz(y, 3, 4)
< < insert Rick Cook quote here > >

User avatar
Kia
Eileen-Class Veteran
Posts: 1040
Joined: Fri Aug 01, 2014 7:49 am
Deviantart: KiaAzad
Discord: Kia#6810
Contact:

Re: save cropped screeshot

#10 Post by Kia »

Unfortunately the function uses another function to capture the screenshot and I can't find the class to add a method to it that returns a full size render

Code: Select all

    def save_screenshot(self, filename):
        """
        Saves a full-size screenshot in the given filename.
        """

        window = renpy.display.draw.screenshot(self.surftree)  #<==========This line

        if renpy.config.screenshot_crop:
            window = window.subsurface(renpy.config.screenshot_crop)

        try:
            renpy.display.scale.image_save_unscaled(window, filename)
            if renpy.emscripten:
                emscripten.run_script(r'''FSDownload('%s');''' % filename)
            return True
        except:
            if renpy.config.debug:
                raise

            return False
everything else seems easy to modify, but this line references a surftree that's created somewhere else and passes it to a function that returns some object that is saved as an image in the next lines.
using renpy.take_screenshot((1920,1080)) and writing the data to file was so easy that I imagined cropping it would need a couple of additional lines, but boy I was wrong. only if I knew of a way to convert a transform like Crop(crop, FileCurrentScreenshot()) back into a format that can be written to file this whole problem would be solved

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2400
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: save cropped screeshot

#11 Post by Ocelot »

So following does not work?

Code: Select all

def save_cropped_screenshot(self, filename, crop):
    window = renpy.display.draw.screenshot(self.surftree)
    window = window.subsurface(crop)
    try:
        renpy.display.scale.image_save_unscaled(window, filename)
        return True
    except:
        if renpy.config.debug:
            raise
        return False

# Later
crop = (100, 200, 50, 50) # Calculated crop
save_cropped_screenshot(renpy.game.interface, "filename.png", crop)
< < insert Rick Cook quote here > >

User avatar
Kia
Eileen-Class Veteran
Posts: 1040
Joined: Fri Aug 01, 2014 7:49 am
Deviantart: KiaAzad
Discord: Kia#6810
Contact:

Re: save cropped screeshot

#12 Post by Kia »

the source of problem is before cropping step, the line window = renpy.display.draw.screenshot(self.surftree) returns a screenshot at the current window size that can be any size in windowed mode, the crop will be inaccurate because of that

User avatar
Ocelot
Lemma-Class Veteran
Posts: 2400
Joined: Tue Aug 23, 2016 10:35 am
Github: MiiNiPaa
Discord: MiiNiPaa#4384
Contact:

Re: save cropped screeshot

#13 Post by Ocelot »

Can you then take take_screenshot as base function and add cropping code from save_screenshot?

something like that:

Code: Select all

def save_scaled_cropped_screenshot(scale, crop, filename):
    surf = renpy.display.draw.screenshot(renpy.game.interface.surftree)
    surf = renpy.display.scale.smoothscale(surf, scale)
    surf = surf.subsurface(crop)
    renpy.display.render.mutated_surface(surf)
    try:
        renpy.display.scale.image_save_unscaled(surf, filename)
        return True
    except:
        if renpy.config.debug:
            raise
        return False

save_scaled_cropped_screenshot(scale=(1920,1080), crop=(910, 490, 100, 100), filename="screen.png")
< < insert Rick Cook quote here > >

User avatar
Kia
Eileen-Class Veteran
Posts: 1040
Joined: Fri Aug 01, 2014 7:49 am
Deviantart: KiaAzad
Discord: Kia#6810
Contact:

Re: save cropped screeshot

#14 Post by Kia »

Ocelot wrote: Mon Apr 26, 2021 4:05 pm Can you then take take_screenshot as base function and add cropping code from save_screenshot?
Thank you, the scaling solved the problem, and sorry about the delayed answer, I got swamped with work and couldn't get any free time for few days ^^

Post Reply

Who is online

Users browsing this forum: AWizardWithWords, NeonNights