Black texture when loading images in runtime on Android

:information_source: Attention Topic was automatically imported from the old Question2Answer platform.
:bust_in_silhouette: Asked By lamelynx

I have built a plugin to get gallery or camera images from Android device.

The problem is i can’t display any texture. It only gets black images. I can store the image as png and display it through filemanager on the device.

I have turned on GLES2 and use Godot 3.2.2.

My code:

var image = Image.new()
var error = image.load_jpg_from_buffer(img_buffer)
if error != OK:
    print("Error loading png/jpg buffer", error)
else:
    var texture = ImageTexture.new()
    texture.create_from_image(image)
    find_node("Image").texture = texture
    		
    # Proof that image is received
    image.save_png("/storage/emulated/0/Android/data/org.godotengine.godotexample/files/image.png")

Where are you getting the image? What code is used to take the picture and assign it to img_buffer?

Ertain | 2020-08-01 23:03

I suspects the format type.?

image.get_format() # Returns '4' in Godot no matter what i do

My plugin Kotlin code:

// Bitmap decode, tried both Alt.1 and Alt.2 with same result
//Alt.1
/*val source = ImageDecoder.createSource(godot.contentResolver,  uri)
val bitmap = ImageDecoder.decodeBitmap(source)*/

//Alt. 2
val opt = BitmapFactory.Options()
opt.inPreferredConfig = Bitmap.Config.ARGB_8888
val inputImage = godot.contentResolver.openInputStream(uri)
val bitmap = BitmapFactory.decodeStream(inputImage, null, opt)!!

// Convert to ByteArray
val stream = ByteArrayOutputStream()
bitmap.compress(Bitmap.CompressFormat.JPEG, 100, stream)
stream.close()

// Return image as PoolByteArray to Godot
emitSignal("image_request_completed", stream.toByteArray())

lamelynx | 2020-08-02 08:42

The code image.get_format() is returning the enumerator FORMAT_RGB8 (more details for those return values can be found here). Maybe when the image data is converted to a ByteArray some of the necessary bits are lost?

Ertain | 2020-08-02 16:17

Thanks for the response.

I actually found a solution
I don’t know why but Godot may need to catch up?:

var image = Image.new()
var error = image.load_jpg_from_buffer(img_buffer)
if error != OK:
    print("Error loading png/jpg buffer", error)
else:
    yield(get_tree(), "idle_frame") # <--This needed, don't know why!?
    var texture = ImageTexture.new()
    texture.create_from_image(image, 0)
    get_node("VBoxContainer/Image").texture = texture

lamelynx | 2020-08-02 18:13