(The driving force behind this admittedly strange question is that I’m looking to make a whole bunch of textures for a Game unrelated to Godot)
I have a texture atlas that has about 256 unique tiles to them, and my idea was to set up a tilemap that I can use as a canvas, then have a script that goes through the whole tilemap, looking for each unique, continuous, arbitrary rectangle/square of tiles to export as a png, also with it’s inverted variant if possible; All my tiles are monochrome.
Would this be a good use of Godot, or is there better software out there that can do the trick more effectively?
Yeah, should be possible. There are a couple ways to do it.
I did it in a dirty and quick way by using a transparent SubViewport and getting the Image from its Texture2D, generating a BitMap from that Image and getting the opaque polygons (the parts of the image that aren’t transparent) with BitMap.opaque_to_polygons(), creating a Rect2 that encloses each polygon and getting the region of the Image with Image.get_region(). Finally saving the final image image as a png
The scene (The Sprite2D is there to test if it’s generating the BitMap correctly)
The script:
extends Node
@onready var sub_viewport: SubViewport = $SubViewportContainer/SubViewport
func _ready() -> void:
# Set viewport as transparent
sub_viewport.transparent_bg = true
# await for the viewport to render
await RenderingServer.frame_post_draw
# get its image
var image = sub_viewport.get_texture().get_image()
# create a BitMap from that image
var bitmap = BitMap.new()
bitmap.create_from_image_alpha(image)
# get the polygons of that image
var polygons = bitmap.opaque_to_polygons(Rect2(Vector2.ZERO, image.get_size()))
var index = 0
# for each polygon, create a rectangle and clip that rectangle from the image and save it
for polygon in polygons:
var rect = Rect2()
rect.position = polygon[0]
for point in polygon:
rect = rect.expand(point)
var output_image = image.get_region(rect)
output_image.save_png('res://clipped_%02d.png' % index)
index += 1
# check that the bitmap is correct
$Sprite2D.texture = ImageTexture.create_from_image(bitmap.convert_to_image())
If the tiles have transparent parts this method won’t work you’ll not need to create a BitMap to create the Rect2 but you’ll need to create the Rect2 using TileMap.get_used_cells() I’ll leave that to you if that’s the case
I think this also depends on how skilled you are already with Godot or other things. If you feel comfortable in Godot, then it is a great tool for this task! However, if you know another language and are more comfortable with that, then it would be worth looking into libraries/frameworks to use that for your task.