Hello! I’ve been having issues with the latest installment, and have been looking for accurate searches with no good results. How do you make a screenshot .png of .jpg in your Android? I was able to only find code for uploading to desktop, and one outdated source with no replacement.
Where do I begin? I’m just trying to access screenshots like any other app but can’t.
You will also need android permissions to write to “external storage” i.e. the phone’s documents
This topic recently covered some of that, hard to follow because of the huge code pastes and little else information. But they claim to get this path to work: "/storage/emulated/0/Pictures/Drawing/" + filename
This is indeed hard to follow. I was able to even find “write external” in project settings. I don’t know where to begin with this example. I even added OS.request_permissions. Look
func _save_image():
OS.request_permissions()
var file_name = “screenshot.png”
var view_image: Image = get_viewport().get_texture().get_image()
view_image.save_png(“user://storage/emulated/0/Pictures/”+file_name)
Does anyone have anything better? Last time I checked, you couldn’t even make screenshots a long time ago.
So I put it in. No dice. It’s outdated at viewport to begin with. Look along with my regular code
extends CanvasLayer
func _request_storage_permissions():
if OS.get_name() == “Android”:
# In Godot 4.3, permissions are handled differently
# You need to declare them in the export template or project settings
OS.request_permissions()
func _export_drawing_to_png():
var image = get_viewport().get_texture().get_image()
image.flip_y()
# Build the save path - Use user:// for Android compatibility
var base_dir: String
if OS.get_name() == "Android":
# On Android, use the app's internal storage or documents directory
base_dir = OS.get_system_dir(OS.SYSTEM_DIR_DOCUMENTS)
if base_dir.is_empty():
# Fallback to user:// directory (app's internal storage)
base_dir = OS.get_user_data_dir()
else:
# On other platforms, use the Pictures directory
base_dir = OS.get_system_dir(OS.SYSTEM_DIR_PICTURES)
var drawing_dir := base_dir.path_join("Drawing")
# Ensure the "Drawing" folder exists
if not DirAccess.dir_exists_absolute(drawing_dir):
var dir_result = DirAccess.make_dir_recursive_absolute(drawing_dir)
if dir_result != OK:
print("❌ Failed to create directory:", drawing_dir, " Error:", dir_result)
return
# Create a filename with a valid timestamp
var timestamp := Time.get_datetime_string_from_system().replace(":", "-").replace(" ", "_")
var filename := "screenshot" + timestamp + ".png"
var file_path := drawing_dir.path_join(filename)
print("📁 Attempting to save to:", file_path)
# Save the image as PNG
# On Android, also try to copy to a more accessible location
if OS.get_name() == "Android":
var accessible_path = "/storage/emulated/0/Pictures/Drawing/" + filename
image.save_png(accessible_path)
I managed to take a screenshot of my drawings on Android. You’ll need to export the drawing in .png format from the viewport to the Documents folder and not to the Pictures folder, because Android doesn’t want to export files to the Pictures folder for security reasons, but also because on Android, the Documents folder isn’t locked, unlike the other folders.
I’ve tried all the other folders other than Pictures without success. Only the Documents folder works.
Also make sure you’re on a recent version of Android as there is no Documents folder on Android 10 and earlier.
Also, remember to check the Read External Storage, Write External Storage, and Manage External Storage permissions when exporting to Android.
Here’s an example of my script so you can get some inspiration.
func request_storage_permissions():
if OS.get_name() == "Android":
# In Godot 4.3, permissions are handled differently
# You need to declare them in the export template or project settings
OS.request_permissions()
func export_drawing_to_png():
var tile_size = tilemap_layer.tile_set.tile_size
var tilemap_size = (max_bounds - min_bounds + Vector2i.ONE) * tile_size
# Create the viewport for capturing the TileMap rendering
var viewport := SubViewport.new()
viewport.size = tilemap_size
viewport.render_target_clear_mode = SubViewport.CLEAR_MODE_ALWAYS
viewport.render_target_update_mode = SubViewport.UPDATE_ONCE
viewport.transparent_bg = false
viewport.disable_3d = true
# Duplicate the TileMap into a temporary container
var container := Node2D.new()
var tilemap_copy := tilemap_layer.duplicate()
tilemap_copy.position = -min_bounds * tile_size # Center at the origin
container.add_child(tilemap_copy)
viewport.add_child(container)
# Add the viewport to the scene so it gets rendered
add_child(viewport)
await RenderingServer.frame_post_draw # Wait for the rendering to complete
# Retrieve the image from the viewport texture
var image = viewport.get_texture().get_image()
# Clean up
remove_child(viewport)
viewport.queue_free()
# Build the save path - Use user:// for Android compatibility
var base_dir: String
if OS.get_name() == "Android":
# On Android, use the app's internal storage or documents directory
base_dir = OS.get_system_dir(OS.SYSTEM_DIR_DOCUMENTS)
if base_dir.is_empty():
# Fallback to user:// directory (app's internal storage)
base_dir = OS.get_user_data_dir()
else:
# On other platforms, use the Pictures directory
base_dir = OS.get_system_dir(OS.SYSTEM_DIR_PICTURES)
var drawing_dir := base_dir.path_join("Drawing")
# Ensure the "Drawing" folder exists
if not DirAccess.dir_exists_absolute(drawing_dir):
var dir_result = DirAccess.make_dir_recursive_absolute(drawing_dir)
if dir_result != OK:
print("❌ Failed to create directory:", drawing_dir, " Error:", dir_result)
return
# Create a filename with a valid timestamp
var timestamp := Time.get_datetime_string_from_system().replace(":", "-").replace(" ", "_")
var filename := "export_tilemap_" + timestamp + ".png"
var file_path := drawing_dir.path_join(filename)
print("📁 Attempting to save to:", file_path)
# Save the image as PNG
var err := image.save_png(file_path)
if err == OK:
print("✅ Export PNG succeeded:", file_path)
# On Android, also try to copy to a more accessible location
if OS.get_name() == "Android":
var accessible_path = "/storage/emulated/0/Pictures/Drawing/" + filename
var copy_err = image.save_png(accessible_path)
if copy_err == OK:
print("✅ Also saved to accessible location:", accessible_path)
else:
print("⚠️ Could not save to accessible location:", copy_err)
else:
print("❌ Error during PNG export:", err)
print("📁 Tried path:", file_path)
I was ‘bout to say, “wait till till Godot creators noticed”, but… SLAM-SLAM-SLAM! I figured it out!
Look, and when they better implement it, get ta changin’
func request_storage_permissions():
if OS.get_name() == “Android”:
# In Godot 4.3, permissions are handled differently
# You need to declare them in the export template or project settings
OS.request_permissions()
func export_drawing_to_png():
var image: Image = get_viewport().get_texture().get_image()
# Build the save path - Use user:// for Android compatibility
var base_dir: String
if OS.get_name() == "Android":
# On Android, use the app's internal storage or documents directory
base_dir = OS.get_system_dir(OS.SYSTEM_DIR_DOCUMENTS)
if base_dir.is_empty():
# Fallback to user:// directory (app's internal storage)
base_dir = OS.get_user_data_dir()
else:
# On other platforms, use the Pictures directory
base_dir = OS.get_system_dir(OS.SYSTEM_DIR_PICTURES)
var drawing_dir := base_dir.path_join("Drawing")
# Ensure the "Drawing" folder exists
if not DirAccess.dir_exists_absolute(drawing_dir):
var dir_result = DirAccess.make_dir_recursive_absolute(drawing_dir)
if dir_result != OK:
print("❌ Failed to create directory:", drawing_dir, " Error:", dir_result)
return
# Create a filename with a valid timestamp
var timestamp := Time.get_datetime_string_from_system().replace(":", "-").replace(" ", "_")
var filename := "export_tilemap_" + timestamp + ".png"
var file_path := drawing_dir.path_join(filename)
print("📁 Attempting to save to:", file_path)
# Save the image as PNG
var err := image.save_png(file_path)
if err == OK:
print("✅ Export PNG succeeded:", file_path)
# On Android, also try to copy to a more accessible location
if OS.get_name() == "Android":
var accessible_path = "/storage/emulated/0/Documents/Drawing/" + filename
var copy_err = image.save_png(accessible_path)
if copy_err == OK:
print("✅ Also saved to accessible location:", accessible_path)
else:
print("⚠️ Could not save to accessible location:", copy_err)
else:
print("❌ Error during PNG export:", err)
print("📁 Tried path:", file_path)