Page 1 of 2
FileTakeScreenshot - Showing screenshot back to player
Posted: Fri Apr 17, 2020 12:54 pm
by Kinmoku
Hi all,
I'm having a little trouble with FileTakeScreenshot. I'm using the freehand_draw discussed in this thread:
viewtopic.php?f=8&t=51370&p=494175#p494175 and I want to take a screenshot of the drawing and show it back to the player.
Here's my code in screens:
Code: Select all
screen freehand_draw():
vbox:
hbox:
frame:
background "#FFF"
padding (0, 0)
xsize 800
ysize 360
add freehand_canvas
hbox:
style "draw_ui"
for colour in colours:
button:
xsize 32
ysize 32
background colour
action SetField(freehand_canvas, 'colour', colour)
textbutton "New sheet" action Function(freehand_canvas.clear)
textbutton "Thicker pen" action SetField(freehand_canvas, 'line_width', 8)
textbutton "Done" action [FileTakeScreenshot(), Return()]
screen pixelart:
add FileTakeScreenshot() xalign 0.5 yalign 0.5
Then, I want to call back to the screenshot in the script:
Code: Select all
v "Let me see what you drew!"
nvl clear
window hide
show screen pixelart
But FileTakeScreenshot() doesn't work. FileCurrentScreenshot() does, but it doesn't take the screenshot at the right moment.
Looking on the forums, I've seen a few people with this issue and I'm not sure if they resolved it, if at all. It seems like it should be possible now, though? Any ideas?
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Mon Apr 20, 2020 11:23 am
by Kinmoku
Bumping if anyone knows how to do this?
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Mon Apr 20, 2020 1:33 pm
by hell_oh_world
Kinmoku wrote: ↑Mon Apr 20, 2020 11:23 am
Bumping if anyone knows how to do this?
Code: Select all
screen pixelart:
add FileTakeScreenshot() xalign 0.5 yalign 0.5
i guess this one should be...
Code: Select all
screen pixelart:
add FileCurrentScreenshot() xalign 0.5 yalign 0.5
also, just to be safe, u might want to set a delay before returning, the screenshot might take a while perhaps?
Code: Select all
screen freehand_draw():
default hide_now = False
vbox:
hbox:
frame:
background "#FFF"
padding (0, 0)
xsize 800
ysize 360
add freehand_canvas
hbox:
style "draw_ui"
for colour in colours:
button:
xsize 32
ysize 32
background colour
action SetField(freehand_canvas, 'colour', colour)
textbutton "New sheet" action Function(freehand_canvas.clear)
textbutton "Thicker pen" action SetField(freehand_canvas, 'line_width', 8)
textbutton "Done" action [FileTakeScreenshot(), SetScreenVariable("hide_now", True)]
if hide_now:
timer 1.5 action Return()
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Mon Apr 20, 2020 3:14 pm
by qirien
I am making a photo album right now where the user can take their own screenshots and it will catalogue them, and here is the code I used. . You do need to have the photos variable initialized with "photos = []" in with your other variables.
Code: Select all
init python:
import os
from datetime import datetime
PHOTO_DIRECTORY = config.gamedir + "/Photos/"
def take_picture():
# Make the directory if needed
if(os.path.isdir(PHOTO_DIRECTORY) == False):
os.mkdir(self.directory)
# Setup the filename
now = datetime.now().strftime("%Y%m%d-%H%M%S")
filename = "Screenshot-" + str(now) + ".png"
# Take the screenshot
result = renpy.screenshot(PHOTO_DIRECTORY + filename)
renpy.transition(Fade(0,0,0.5,color=(255,255,255,255)))
if (result):
photos.append(filename)
renpy.notify("Screenshot Saved! " + filename)
else:
renpy.notify("Could not take screenshot! " + filename)
return
label photo:
# Hide the dialogue window for the picture
window hide
$ renpy.pause(0.3)
$ take_picture()
# Re-show the dialogue window and continue
window auto
return
When you want to take a picture, you can use the screen action
I also wrote a gallery program to view the photos:
Code: Select all
init -10:
# A thumbnail version of a full screen image
transform thumbnail:
zoom 0.28
# Display all the photos taken
# TODO: Store metadata such as year taken, and group accordingly?
screen photo_album():
frame:
vbox:
area (60, 50, 1150, 620)
yfill True
hbox:
xfill True
yfill True
frame:
yfill True
vbox:
label "Photo Album"
vpgrid:
cols 3
spacing 5
mousewheel True
scrollbars "vertical"
side_xalign 0.5
ysize 510
for photo in photos:
$ photo_file = "Photos/" + photo
imagebutton:
idle photo_file
hover photo_file
at thumbnail
action Show("show_photo", irisout, photo_file)
textbutton "Return" action Return() xalign 0.5 yalign 0.5
# Show one photo, full screen.
# When you click, hide it.
# TODO: Add deleting photos, sharing photos?
screen show_photo(photo):
imagebutton:
idle photo
hover photo
action Hide("show_photo", irisin)
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Tue Apr 21, 2020 3:21 am
by Kinmoku
Thanks both.
qirien wrote: ↑Mon Apr 20, 2020 3:14 pm
I am making a photo album right now where the user can take their own screenshots and it will catalogue them, and here is the code I used. . You do need to have the photos variable initialized with "photos = []" in with your other variables.
I plan on showing many photos throughout the game so your code sounds like the kind of thing I'm after
However, I pasted it in and I get the error:
Code: Select all
I'm sorry, but an uncaught exception occurred.
While running game code:
File "game/script.rpy", line 184, in script
$ take_picture()
File "game/script.rpy", line 184, in <module>
$ take_picture()
File "game/script.rpy", line 41, in take_picture
os.mkdir(self.directory)
NameError: global name 'self' is not defined
-- Full Traceback ------------------------------------------------------------
Full traceback:
File "game/script.rpy", line 184, in script
$ take_picture()
File "/Applications/renpy-6.99.11-sdk/renpy/ast.py", line 914, in execute
renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
File "/Applications/renpy-6.99.11-sdk/renpy/python.py", line 2028, in py_exec_bytecode
exec bytecode in globals, locals
File "game/script.rpy", line 184, in <module>
$ take_picture()
File "game/script.rpy", line 41, in take_picture
os.mkdir(self.directory)
NameError: global name 'self' is not defined
It seems to be "$ take_picture()" is not defined... I'm not good at python so I don't fully understand, but could there be some missing parts to the code?
Thanks again
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Tue Apr 21, 2020 8:01 am
by hell_oh_world
Code: Select all
-- Full Traceback ------------------------------------------------------------
Full traceback:
File "game/script.rpy", line 184, in script
$ take_picture()
File "/Applications/renpy-6.99.11-sdk/renpy/ast.py", line 914, in execute
renpy.python.py_exec_bytecode(self.code.bytecode, self.hide, store=self.store)
File "/Applications/renpy-6.99.11-sdk/renpy/python.py", line 2028, in py_exec_bytecode
exec bytecode in globals, locals
File "game/script.rpy", line 184, in <module>
$ take_picture()
File "game/script.rpy", line 41, in take_picture
os.mkdir(self.directory)
NameError: global name 'self' is not defined
should be...
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Tue Apr 21, 2020 9:20 am
by Kinmoku
hell_oh_world wrote: ↑Tue Apr 21, 2020 8:01 am
should be...
CODE: SELECT ALL
os.mkdir(PHOTO_DIRECTORY)
Thanks
This fixed it. I also added "define photos = []" to script.rpy.
I am still having an issue, though. Because I want to take a photo of the drawing (freehand_draw), the screen needs to stay open as the photo code works. I changed "call screen freehand_draw" to "show screen freehand_draw", added "modal True", and the screen stays open but doesn't take_picture. Here's my code:
Code: Select all
screen freehand_draw():
modal True
vbox:
hbox:
#vbox:
#style "draw_ui"
#imagebutton idle "pencil_icon.png" hover pencil_hover_icon selected_idle pencil_hover_icon action SetField(freehand_canvas, 'mode', FreehandCanvas.PENCIL)
frame:
background "#FFF"
padding (0, 0)
xsize 800
ysize 360
add freehand_canvas
hbox:
style "draw_ui"
for colour in colours:
button:
xsize 32
ysize 32
background colour
action SetField(freehand_canvas, 'colour', colour)
textbutton "New sheet" action Function(freehand_canvas.clear)
textbutton "Thicker pen" action SetField(freehand_canvas, 'line_width', 8) ## NEEDED?
textbutton "Done" action Call("photo")
In script.rpy:
Code: Select all
v "Have a go!"
show screen freehand_draw
e "Er..."
v "Let me see!"
nvl clear
window hide
call screen photo_album # this works
# etc
label photo:
# Hide the dialogue window for the picture
#window hide
e "test 1"
$ renpy.pause(0.2)
$ take_picture()
e "test 2"
hide screen freehand_draw
# Re-show the dialogue window and continue
#window auto
return
"test 1" will display but the photo will not take and "test 2" doesn't appear, suggesting the take_picture code doesn't like using show screen. Is there a way I can get it to take a screenshot of freehand_draw before it closes?
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Tue Apr 21, 2020 9:43 am
by hell_oh_world
Kinmoku wrote: ↑Tue Apr 21, 2020 9:20 am
hell_oh_world wrote: ↑Tue Apr 21, 2020 8:01 am
should be...
CODE: SELECT ALL
os.mkdir(PHOTO_DIRECTORY)
Thanks
This fixed it. I also added "define photos = []" to script.rpy.
I am still having an issue, though. Because I want to take a photo of the drawing (freehand_draw), the screen needs to stay open as the photo code works. I changed "call screen freehand_draw" to "show screen freehand_draw", added "modal True", and the screen stays open but doesn't take_picture. Here's my code:
Code: Select all
screen freehand_draw():
modal True
vbox:
hbox:
#vbox:
#style "draw_ui"
#imagebutton idle "pencil_icon.png" hover pencil_hover_icon selected_idle pencil_hover_icon action SetField(freehand_canvas, 'mode', FreehandCanvas.PENCIL)
frame:
background "#FFF"
padding (0, 0)
xsize 800
ysize 360
add freehand_canvas
hbox:
style "draw_ui"
for colour in colours:
button:
xsize 32
ysize 32
background colour
action SetField(freehand_canvas, 'colour', colour)
textbutton "New sheet" action Function(freehand_canvas.clear)
textbutton "Thicker pen" action SetField(freehand_canvas, 'line_width', 8) ## NEEDED?
textbutton "Done" action Call("photo")
In script.rpy:
Code: Select all
v "Have a go!"
show screen freehand_draw
e "Er..."
v "Let me see!"
nvl clear
window hide
call screen photo_album # this works
# etc
label photo:
# Hide the dialogue window for the picture
#window hide
e "test 1"
$ renpy.pause(0.2)
$ take_picture()
e "test 2"
hide screen freehand_draw
# Re-show the dialogue window and continue
#window auto
return
"test 1" will display but the photo will not take and "test 2" doesn't appear, suggesting the take_picture code doesn't like using show screen. Is there a way I can get it to take a screenshot of freehand_draw before it closes?
u might need to replace the done action with the take_picture function
Code: Select all
textbutton "Done" action Function(take_picture)
also why are you trying to show the canvas? doesn't that will cause the user to proceed to the next dialogues freely while drawing? i mean, when they're drawing things, the user must not be able to proceed to the next statements, that's the purpose of call right? I don't have much experience with calls, sorry.
Note: i suggest making the action button first with no return action, then show the photo or what... and from my previous post before, try also setting a delay before returning or hiding the canvas, better to be safe than sorry though, its in my previous post.
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Tue Apr 21, 2020 10:04 am
by Kinmoku
hell_oh_world wrote: ↑Tue Apr 21, 2020 9:43 am
u might need to replace the done action with the take_picture function
CODE: SELECT ALL
textbutton "Done" action Function(take_picture)
Awesome
Works like a charm!
hell_oh_world wrote: ↑Tue Apr 21, 2020 9:43 am
also why are you trying to show the canvas? doesn't that will cause the user to proceed to the next dialogues freely while drawing? i mean, when they're drawing things, the user must not be able to proceed to the next statements, that's the purpose of call right? I don't have much experience with calls, sorry.
Calling the screen meant it left it when the button was pressed, so the screenshot never took the photo of the artwork. Your code fixed this though
hell_oh_world wrote: ↑Tue Apr 21, 2020 9:43 am
Note: i suggest making the action button first with no return action, then show the photo or what... and from my previous post before, try also setting a delay before returning or hiding the canvas, better to be safe than sorry though, its in my previous post.
You make a great point. I was going to add this once I got it working.
My final code is below. I just have one question about how I can change take_picture to include my desired screenshot crop "define config.screenshot_crop = (0, 0, 800, 360)" ?
Code: Select all
define photos = []
# PHOTOS
init python:
import os
from datetime import datetime
PHOTO_DIRECTORY = config.gamedir + "/Photos/"
def take_picture():
# Make the directory if needed
if(os.path.isdir(PHOTO_DIRECTORY) == False):
os.mkdir(PHOTO_DIRECTORY)
# Setup the filename
now = datetime.now().strftime("%Y%m%d-%H%M%S")
filename = "Screenshot-" + str(now) + ".png"
# Take the screenshot
result = renpy.screenshot(PHOTO_DIRECTORY + filename)
renpy.transition(Fade(0,0,0.5,color=(255,255,255,255)))
if (result):
photos.append(filename)
renpy.notify("Screenshot Saved! " + filename)
else:
renpy.notify("Could not take screenshot! " + filename)
return
init -10:
# A thumbnail version of a full screen image
transform thumbnail:
zoom 0.28
label start:
v "Have a go!"
call screen freehand_draw
e "Er..."
v "Let me see!"
nvl clear
window hide
call screen photo_album
Code: Select all
screen freehand_draw():
default hide_now = False
vbox:
hbox:
#vbox:
#style "draw_ui"
#imagebutton idle "pencil_icon.png" hover pencil_hover_icon selected_idle pencil_hover_icon action SetField(freehand_canvas, 'mode', FreehandCanvas.PENCIL)
frame:
background "#FFF"
padding (0, 0)
xsize 800
ysize 360
add freehand_canvas
hbox:
style "draw_ui"
for colour in colours:
button:
xsize 32
ysize 32
background colour
action SetField(freehand_canvas, 'colour', colour)
textbutton "New sheet" action Function(freehand_canvas.clear)
textbutton "Thicker pen" action SetField(freehand_canvas, 'line_width', 8)
textbutton "Done" action [Function(take_picture), SetScreenVariable("hide_now", True)]
if hide_now:
timer 1.0 action Return()
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Tue Apr 21, 2020 11:18 am
by qirien
Thanks for finding that directory bug!
I don't see a way to pass a screenshot size/crop area to renpy.screenshot. You could try config.screenshot_crop, but it might just be for screenshots for saved games, which are taken with FileTakeScreenshot. I think you can get the screenshot it takes with FileCurrentScreenshot, which returns a Displayable, which you could then write out with python file code.
This is similar to the method used by
this cell phone emulationcode, so you might take a look at that if you need just a certain part of the screen.
Or, you could have the screenshot be full size and just crop it when you show it in the gallery with a transform like this. Use "at crop_drawing" in your gallery when displaying an image:
Code: Select all
transform crop_drawing:
crop (0,0,800,306)
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Tue Apr 21, 2020 11:53 am
by hell_oh_world
Kinmoku wrote: ↑Tue Apr 21, 2020 10:04 am
hell_oh_world wrote: ↑Tue Apr 21, 2020 9:43 am
u might need to replace the done action with the take_picture function
CODE: SELECT ALL
textbutton "Done" action Function(take_picture)
Awesome
Works like a charm!
hell_oh_world wrote: ↑Tue Apr 21, 2020 9:43 am
also why are you trying to show the canvas? doesn't that will cause the user to proceed to the next dialogues freely while drawing? i mean, when they're drawing things, the user must not be able to proceed to the next statements, that's the purpose of call right? I don't have much experience with calls, sorry.
Calling the screen meant it left it when the button was pressed, so the screenshot never took the photo of the artwork. Your code fixed this though
hell_oh_world wrote: ↑Tue Apr 21, 2020 9:43 am
Note: i suggest making the action button first with no return action, then show the photo or what... and from my previous post before, try also setting a delay before returning or hiding the canvas, better to be safe than sorry though, its in my previous post.
You make a great point. I was going to add this once I got it working.
My final code is below. I just have one question about how I can change take_picture to include my desired screenshot crop "define config.screenshot_crop = (0, 0, 800, 360)" ?
i dunno how are you showing or retaining the shot image, so i modified it a bit...
Code: Select all
default last_screenshot = "" # takes note of the recent screenshot
init python:
import os
from datetime import datetime
PHOTO_DIRECTORY = config.gamedir + "/Photos/"
def take_picture():
# Make the directory if needed
if(os.path.isdir(PHOTO_DIRECTORY) == False):
os.mkdir(PHOTO_DIRECTORY)
# Setup the filename
now = datetime.now().strftime("%Y%m%d-%H%M%S")
filename = "Screenshot-" + str(now) + ".png"
store.last_screenshot = filename # store the last screenshot name
# Take the screenshot
result = renpy.screenshot(PHOTO_DIRECTORY + filename)
renpy.transition(Fade(0,0,0.5,color=(255,255,255,255)))
if (result):
photos.append(filename)
renpy.notify("Screenshot Saved! " + filename)
else:
renpy.notify("Could not take screenshot! " + filename)
return
screen the_shot(image, crop=None):
default the_image = image if not crop else Crop(crop, image)
add the_image
label sample:
## Some codes before showing...
show screen the_shot(last_screenshot, (0, 0, 800, 360)) # show / call the screen together with the image name and an optional crop value...
https://www.renpy.org/doc/html/displayables.html#Crop
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Tue Apr 21, 2020 12:48 pm
by Kinmoku
qirien wrote: ↑Tue Apr 21, 2020 11:18 am
This is similar to the method used by this cell phone emulationcode, so you might take a look at that if you need just a certain part of the screen.
This post is awesome! I'll check over it in more detail soon.
As you've both suggested, Crop is the best solution here. However, it doesn't display correctly if the window is fullscreen or smaller. I'm not sure what the solution is to that
Anyway, I have changed the filename code to the below:
Code: Select all
init python:
import os
#from datetime import datetime
PHOTO_DIRECTORY = config.gamedir + "/photos/"
def take_picture():
# Make the directory if needed
if(os.path.isdir(PHOTO_DIRECTORY) == False):
os.mkdir(PHOTO_DIRECTORY)
# Take the screenshot
result = renpy.screenshot(PHOTO_DIRECTORY + filename)
renpy.transition(Fade(0,0,0.5,color=(255,255,255,255)))
photos.append(filename)
return
image photo_first = "photos/screenshot-first.png"
label start:
v "Have a go!"
$ filename = "screenshot-first.png"
call screen freehand_draw
e "Er..."
v "Let me see!"
nvl clear
show photo_first at crop_drawing
pause
hide photo_first
It worked the first time I tested, but when I try again, it shows my drawing from a previous test. I guess when the game loaded, it loaded the previous image. How can I refresh it? Sorry for so many questions! I'm learning a lot today lol
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Tue Apr 21, 2020 1:13 pm
by qirien
The problem with statically declaring your image is that images get cached - Ren'Py loads them once and then keeps them around and doesn't reload them unless you haven't used them for a long time. This is also the reason that you can't declare images after your code starts. So you need to show your image in a way that will reload it from disk... which is why I ended up using imagebutton where you give it, not an image, but a filename. This will make sure it loads it every time.
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Wed Apr 22, 2020 4:14 am
by Kinmoku
qirien wrote: ↑Tue Apr 21, 2020 1:13 pm
The problem with statically declaring your image is that images get cached - Ren'Py loads them once and then keeps them around and doesn't reload them unless you haven't used them for a long time. This is also the reason that you can't declare images after your code starts. So you need to show your image in a way that will reload it from disk... which is why I ended up using imagebutton where you give it, not an image, but a filename. This will make sure it loads it every time.
Ah, very smart! So I can use imagebutton or something and add Nullaction to it
Cool.
I'm still unsure about the game window size and ensuring the crop is the same each time. Is there a way for screenshots to be taken at 100% size, regardless of whether the window is actually 50%, fullscreen etc?
Re: FileTakeScreenshot - Showing screenshot back to player
Posted: Wed Apr 22, 2020 1:57 pm
by qirien
Ugh... you're right. It works fine at the default window size, but in full screen it doesn't work at all...
BUT, I think once again transforms will be our friend! I changed the thumbnail transform and added another one for full screen:
Code: Select all
# A thumbnail version of a full screen image
transform thumbnail:
#zoom 0.22 #doesn't work if full screen
size (282,159)
# Display something the size of our screen
transform full_screen:
size (1280,720) #Change to whatever the resolution of your game is
When we display the images, use "at full_screen" like this:
Code: Select all
screen show_photo(photo):
imagebutton:
idle photo
hover photo
action Hide("show_photo", irisin)
at full_screen
Even though when you run at full screen it's larger than 1280x720, Ren'Py still considers whatever resolution your game is at to be "full screen". So you can tell it to use absolute pixel sizes and it will just scale them up if people are running it at a higher resolution.