How to save an image to sdcard on Android?

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By vinod
:warning: Old Version Published before Godot 3 was released.

I’ve been trying to save an image to sdcard on Android. I tried so many ways.
I created a com.packagename.gamename directory inside /mnt/Android/data to save the image.

I know that GLES2 doesn’t support reading back GPU and it won’t work if I try get_texture().get_data().save_png

But I can create an image like this

var i = Image(100,100,false,Image.FORMAT_RGBA)
i.save_png(path)

And also I can save the screenshot image like this

get_viewport().queue_screen_capture()
yield(get_tree(),"idle_frame")
yield(get_tree(),"idle_frame")
get_viewport().get_screen_capture().save_png(path)

All the working things are Image type, but this doesn’t work

var i = Image()
i.load("res://path_to_image.png")
i.save_png(path)

I’ve also tried reading the image file and copy to the destination directory using

var src = File.new()
src.open("source_path.png",File.READ)
var buffer = src.get_buffer(src.get_len()) #some error at get_len() on android

var dest = File.new()
dest.open("dest_path.png",File.WRITE)
dest.store_buffer(buffer)
dest.close()

This also does not work

var d = Directory.new()
d.copy("source_path.png","dest_path.png")

All the above things does work on PC but not on Android.

So, is there any other way to save an image to disk other than adding the image to scene and saving the screenshot?
(Why the screenshot image does save, while others not saving? Can I recreate the an image with “required image data” similar to the screenshot image?)

Works on PC on release mode too? I believe that only save files on user://
Also, check on github, I think there are some issues related to writing files on Android

eons | 2016-10-21 23:15

Works on pc means inside the editor.

This not copying is not the problem of actual writing to the disk.
It is a problem with we can’t read back textures from gpu.

The screenshot image can be saved while an image from res:// is not saved. Both are the same Godot Image type, and I don’t know what is the difference between them which prevents one from saving or reading from the disk.

I’ll also check if this is a problem of reading images from the res://

vinod | 2016-10-22 01:28

:bust_in_silhouette: Reply From: KenHuang0917

I had the same problem and with Zylann’s help I solved it luckily. What I have done is writing a Java singleton and make it returns the path you need. You can refer to this link. Hope it helps!

:bust_in_silhouette: Reply From: KoBeWi

This is old question, so these methods might’ve not existed then, but this works:
image.save_png(OS.get_system_dir(OS.SYSTEM_DIR_PICTURES).path_join("image.png"))
(plus_file() instead of path_join() if using Godot 3)

I didn’t test, but you might need to enable some permissions, namely the ones with EXTERNAL_STORAGE in name.