https://kotlinlang.org logo
Title
m

Michael Paus

08/25/2021, 2:51 PM
Does Compose provide any platform independent way to create an ImageBitmap from an encoded byte array? Currently I use two different implementations of that: On Android I use
override fun imageBitmapFromBytes(encodedImageData: ByteArray): ImageBitmap {
    val bitmap = BitmapFactory.decodeByteArray(encodedImageData, 0, encodedImageData.size)
    return bitmap.asImageBitmap()
}
and on Desktop I use
override fun imageBitmapFromBytes(encodedImageData: ByteArray): ImageBitmap {
    return Image.makeFromEncoded(encodedImageData).asImageBitmap()
}
but I think something like this actually belongs into Compose itself. One also might add a similar method to construct an ImageBitmap from a raw bitmap represented as a byte array plus some image info needed to reconstruct the image. What do you think?
r

romainguy

08/25/2021, 4:00 PM
This would require Compose to have its own suite of image decoders which is not something we want to have (at least at this point). Building an
ImageBitmap
from a byte array would make sense but we would need to know the layout of said byte array (ARGB vs RGBA vs BGRA vs ABGR for instance, and that’s only for 8-bit encodings), which you would obtain from the platform’s native bitmap object anyway
j

jim

08/25/2021, 4:08 PM
You can easily build your own such API using expect/actuals.
m

Michael Paus

08/25/2021, 4:11 PM
@jim Yes, certainly. That’s what I am doing right now. But don’t you think that such a common task should be handled transparently by Compose itself?
j

jim

08/25/2021, 4:19 PM
Probably / intuitively I would have thought so, but I would need to sync with Romain and better understand his concern first. For instance, I don't know if ARGP/RGBA/BGRA/ABGR are automatically handled by the existing decoder functions or if those are making format assumptions - just not familiar enough with the space to make a firm statement myself.
m

Michael Paus

08/25/2021, 4:28 PM
Just to avoid any confusion. We are talking about two different cases here. The first case is reading an image from encoded data. That is nothing but the byte representation of a JPEG, PNG, etc. So this case is already fully handled by the platform code for which I have provided examples. The problem here is only that the various platforms use different code to do that and I would like to avoid having to let all users having to deal with that themselves. The second case is reading an image from raw bitmap data. In this case it would need a common description of the image layout as I said already above. The various platforms already can do that but once again in different ways.
r

romainguy

08/25/2021, 4:39 PM
The second case is a bit more complicated. Android for instance only understands ARGB for 8-bit data, not RGBA/etc. Supporting generic layouts would require extra work would require to build a conversion pipeline. I’m not saying it’s not worth it or difficult, just not straightforward.
Anyway, at the very least it seems like providing an equivalent of your
imageBitmapFromBytes
as a platform-specific implementation that just delegates to platform-specific decoders + extension methods would make sense.
Although I wonder how common it is in apps to decode from a byte array? On Android decoding is more commonly done from resource ids or input streams
j

jim

08/25/2021, 4:47 PM
Decoding from byte arrays is equivalent to decoding from inputstream, it is easy to use the two interchangeably, and providing either one would likely solve the above user's needs. I often read an inputstream to a bytearray just because it allows me to check the size, use it twice, etc. I think the problem is that at the moment, we provide neither decode-from-bytearray nor decode-from-inputstream as a platform-independent API.
If I'm reading the above correctly, sounds to me like maybe Romain doesn't have any objections to the first use case. @Michael Paus want to file a bug against Compose and link it here?
m

Michael Paus

08/25/2021, 4:51 PM
Reading from a stream would be ok for me too. Possible use-cases are for example reading images as BLOBs from a database or, as in my case, from some proprietary data formats.
j

jim

08/25/2021, 4:52 PM
Well, I think reading from ByteArray is an easier API to support since ByteArray is MPP but InputStream is not. Would need to take a 3rd party dependency in order to support some sort of streaming API.
m

Michael Paus

08/25/2021, 4:54 PM
So one more reason for the ByteArray variant. I’ll file a bug for it.
Here is the link to the issue: https://github.com/JetBrains/compose-jb/issues/1113
👍 2
:tnx: 1