Godot 4 Android file picker returns content:// URI, cannot load image with Image.load_from_file()

Godot 4.7

Godot 4.7

Question

Hi everyone,

I am working on a Godot 4 project for Android. I am using the default Android file picker, and when I select an image I receive a path like this:

content://com.android.externalstorage.documents/document/primary%3APictures%2F1566307961577.jpg

I am trying to load the image using:

var image = Image.load_from_file(path) 
if image == null: 
     print("Failed to load image")

but it fails.

I tried converting the URI to a normal storage path:

/storage/emulated/0/

but that does not work.

I also checked Android permissions, but the problem seems to be that content:// is not a real filesystem path and Android’s Storage Access Framework is returning a URI instead.

What is the recommended way to handle this in Godot 4?

Should I:

  • copy the file from the content:// URI into user:// or cache storage first?
  • use an Android plugin/helper to read the URI?
  • use another file picker approach?

I would appreciate an example of the correct Godot 4 Android workflow for loading images selected from the system picker.

Thanks!

In your export settings for Android, have you set the READ_MEDIA_IMAGES permission to true?

Furthermore iirc, the permission will also have to be granted by the app user.

Below are my notes from a previous project that might be of help:


So far, it seems that the only permission the app needs is android.permission.READ_MEDIA_IMAGES, but that may change if I need to write tmp files from the image selector somewhere before processing.

However, just selecting the permission from the Export dialog will not actually grant it. The user will have to manually grant the permission via Settings in Android, or the app will programmatically have to make the request. It can be done with OS.request_permission.


And here is a snippet of code from that project to serve as an example:

func get_os_permissions() -> bool:
    if OS.get_name() == "Android":
        var already_granted = OS.request_permission("android.permission.READ_MEDIA_IMAGES")
        if already_granted:
            return true
    else:
        return true
    return false

Then using it:

 func _on_inset_button_button_up():
    var perms_ok = await get_os_permissions()
    if perms_ok:
        $BottomPanel/CustomInsetsDialog.popup_centered(Vector2(700, 400))

every permission have been granted , i can also get the file path but the file path is like this : “content://com.android.externalstorage.documents/document/primary%3APictures%2F1566307961577.jpg” which can’t be loaded

So, I could be wrong, but I’m pretty sure this is not a recognized / valid path by the Godot filesystem.

The only two that I know of are res:// and user://, see:

yeah , its the file path provided by android system that’s why godot isn’t able to read it, res:// file path is for reading file which is inside the godot project and user:// is for reading file some temporary folder outside of godot project, but here i am trying to read an external file which is outside the godot project some where in phone’s internal storage …

Have you tried just using Image.load() instead of Image.load_from_file()? You at least should be able to see which exact error you’re getting.

NM

Okay, based on this comment, maybe you have to use FileAccess to get files from “content://” style URI.

Maybe something like:

var image_bytes: PackedByteArray = FileAccess.get_file_as_bytes(path)

var error = img.load_png_from_buffer(image_bytes)
if error == OK:
    var texture = ImageTexture.create_from_image(error)

Just a basic example for you to try–you’ll eventually have to figure out which image loading fn to use (png, jpg, etc) maybe based on the file extension.

I belive that to load such files from internal storage you need to use the FileAccess class with the get_file_as_bytes() method

I believe get_file_as_bytes() accepts content:// URIs, maybe try to use that instead, just like how @nomad2097 suggested

Documentation reference: FileAccess — Godot Engine (stable) documentation in English

Thanks for the solution !!! It was help ful

Thanks for the confirmation. It helped !!!