GifView.kt 1.7 KB

1234567891011121314151617181920212223242526272829303132333435363738394041424344454647
  1. package eu.mjdev.desktop.components.image
  2. import androidx.compose.foundation.Canvas
  3. import androidx.compose.foundation.layout.BoxWithConstraints
  4. import androidx.compose.runtime.*
  5. import androidx.compose.ui.Modifier
  6. import androidx.compose.ui.graphics.toComposeImageBitmap
  7. import androidx.compose.ui.unit.IntSize
  8. import eu.mjdev.desktop.helpers.gif.GifDecoder
  9. import kotlinx.coroutines.delay
  10. import java.awt.image.BufferedImage
  11. import java.io.File
  12. import java.io.FileInputStream
  13. @Composable
  14. fun GifView(
  15. modifier: Modifier = Modifier,
  16. src: String
  17. ) = BoxWithConstraints {
  18. val file by remember(src) { mutableStateOf(File(src)) }
  19. val streamData by remember(file) { mutableStateOf(FileInputStream(file)) }
  20. val gifDecoder by remember(streamData) { mutableStateOf(
  21. GifDecoder().apply { read(streamData) }) }
  22. val framesCount by remember(gifDecoder) { mutableStateOf(gifDecoder.frameCount) }
  23. var currentFrame by remember(gifDecoder) { mutableStateOf(0) }
  24. var decodedImage by remember { mutableStateOf<BufferedImage?>(null) }
  25. Canvas(
  26. modifier = modifier
  27. ) {
  28. decodedImage?.toComposeImageBitmap()?.let { img ->
  29. drawImage(
  30. image = img,
  31. srcSize = IntSize(img.width, img.height),
  32. dstSize = IntSize(constraints.maxWidth, constraints.maxHeight),
  33. )
  34. }
  35. }
  36. LaunchedEffect(currentFrame, decodedImage) {
  37. decodedImage = gifDecoder.getFrame(currentFrame)
  38. delay(gifDecoder.getDelay(currentFrame).toLong())
  39. var nextFrame = currentFrame + 1
  40. if (nextFrame > framesCount) {
  41. nextFrame = 0
  42. }
  43. currentFrame = nextFrame
  44. }
  45. }