Attention | Topic was automatically imported from the old Question2Answer platform. | |
Asked By | AlvaroAV | |
Old Version | Published before Godot 3 was released. |
What I’m doing ?:
- I’m trying to have a scene for a player to customize the player outfit.
- The player Sprite is made of 3 sprites: body, eyes & mouth.
- There are independant png images for the different bodies, eyes and mouths.
The code I’m trying:
# Create Image objects and load the png's
var body = Image()
var eyes = Image()
body.load("res://path_to_png")
eyes.load("res://path_to_png")
# TRY1 - Draw the eyes over the body
body.blit_rect(eyes, Rect2(0,0,100,100), Vector2(15, 20))
# TRY2 - Brush the eyes as a mask on the body
body.brush_transfer(eyes, eyes, Vector2(15, 20))
# Save the image to new route
body.save_png("res://assets/generated/g_body.png")
TRY1: This almost did the trick but the problem is the eyes are not “drawn” over the body so the background is empty.
Example generated Image:
It’s not quite clear but the space between the eyes is transparent, and what I need is to see the body under the eyes
TRY2: I don’t quite understand the functionality of brush_transfer and couldn’t find any good example, maybe anybody can point me to some tutorial on this. When I save the image using brush_transfer
only the body image is shown
##Questions:
- Is there any better way to achieve what I’m trying to do ?
- Is there any way to get an
Image
object from aSprite
orTexture
? - Is there a way to
set_modulate
on aImage
object? - Is there any good tutorial besides the official docs about editing images programmatically ?
I started a few days ago with Godot and everything is new to me, I just checked the offical docs and this site. If there is any other good forum or page I can check for help I appreciate any recommendation.
Thanks
Edit
I tried to achieve something like @raymoo suggested using a Viewport.
My goal was:
- Add an “invisible”
Viewport
into my scene ( I don’t need the user to see this Viewport) - Draw 3 sprites on the viewport (Body, eyes & mouth)
- Get an
Image
object from the Viewport with:myviewport.get_screen_capture()
- Save the image to
Assets
to use it later
My problem is the get_screen_capture()
is allways empty. I tried all the configuration I could and check all the properties of Viewport
on the official docs. I also used get_screen_capture()
on the main viewport and works fine, it returns a screenshot of the game.
- Why the “sub” viewport I created return an empty png ?
- I looked for information about initializing a Viewport programmatically but found nothing. Can someone suggest how a Viewport can be initialized ?
- Is possible to have this Viewport outside the visible game ? I just need this Viewport to generate a custom image, I don’t need the user to see this
The code I’ve tried with Viewport solution (This code is inside a script that belongs to a Node on my main scene):
var body_texture = preload("res:/path_to_body.png")
var eyes_texture = preload("res://path_to_eyes.png")
var body = Sprite.new()
var eyes = Sprite.new()
var vps = Viewport.new()
eyes.set_texture(eyes_texture)
body.set_texture(body_texture)
vps.add_child(body)
vps.add_child(eyes)
add_child(vps)
get_viewport().queue_screen_capture()
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
yield(get_tree(), "idle_frame")
var result = vps.get_screen_capture()
result.save_png("res://assets/images/generated/result.png")
Maybe a bit hacky but for 1 and 2 you could use Viewport.get_screen_capture()
on a Viewport with the things to composite.
raymoo | 2017-03-07 06:36
2 - You can get the ImageTexture
resource from the Sprite
node, then get the Image
data from the texture.
3 - Image is a built-in type, not even a Resource, the modulation is a CanvasItem node property, maybe there is a way to work over the RawArray from the Image or paint each pixel with a mix technique.
4 - Is not a basic nor common thing to work over raw image data so examples of that will be hard to find for now.
eons | 2017-03-07 13:33
Thanks for your info, I tried to achieve something like that but I don’t know how to make a Viewport visible inside my main node. I edited the question with more info
AlvaroAV | 2017-03-07 18:16
To use get_screen_capture
you need to queue_screen_capture
first and wait a couple of frames.
eons | 2017-03-09 14:46
Thanks for the info @eons but I already added those lines to wait a couple of frames. That’s not the problem, I think the Viewport I’m creating programatically is not being displayed anywhere. I added a sample of the code I’m trying with the Viewport
AlvaroAV | 2017-03-09 15:00