KiteImage

fun KiteImage(data: ByteArray, contentDescription: String?, modifier: Modifier = Modifier, alignment: Alignment = Alignment.Center, contentScale: ContentScale = ContentScale.Fit, alpha: Float = DefaultAlpha, colorFilter: ColorFilter? = null, filterQuality: FilterQuality = DrawScope.DefaultFilterQuality, animate: Boolean = true, onError: (ImageDecodeException) -> Unit? = null)

Display any image KiteImage can decode: and it decides on its own whether to animate. Feed it a GIF and it plays (correct delays, disposal compositing, NETSCAPE loop count, holding the last frame after a finite loop ends); feed it a PNG/BMP and it just draws. One composable, no format branching at call sites.

Decoding runs off the UI thread (Dispatchers.Default) and re-runs when data changes. Until it finishes (or on failure) the composable occupies its layout slot but draws nothing; failures also reach onError if provided.

Playback is KiteAnimatedImage: frame selection by elapsed frame-clock time, so long loops never drift and janky frames get skipped, not stretched.

animate is the escape hatch: false pins the first composited frame of an animated input (thumbnails, previews). Static inputs ignore it.


fun KiteImage(bitmap: KiteBitmap, contentDescription: String?, modifier: Modifier = Modifier, alignment: Alignment = Alignment.Center, contentScale: ContentScale = ContentScale.Fit, alpha: Float = DefaultAlpha, colorFilter: ColorFilter? = null, filterQuality: FilterQuality = DrawScope.DefaultFilterQuality)

Display an already-decoded KiteBitmap (for callers running their own decode pipeline). Conversion to ImageBitmap is remembered per instance.