UdaraWanasinghe / webp-android

libwebp JNI bindings to encode a series of Android bitmap images to an animated WebP image.
MIT License
14 stars 0 forks source link

encode gif to anim webp #5

Closed zubinxiong closed 1 year ago

zubinxiong commented 1 year ago
val webPAnimEncoder = WebPAnimEncoder(width = 512, height = 512,
                    options = WebPAnimEncoderOptions(
                        minimizeSize = true,
                        animParams = WebPMuxAnimParams(
                            backgroundColor = Color.TRANSPARENT,
                            loopCount = 0
                        )
                    )
                )

 webPAnimEncoder.configure(
                    config = WebPConfig(
                        lossless = WebPConfig.COMPRESSION_LOSSY
                    ),
                    preset = WebPPreset.WEBP_PRESET_PICTURE
                )

 val gifDrawable = GifDrawable(source.file)
                var time = 0L
                for (i in 0 until gifDrawable.numberOfFrames) {
                    val bitmap = gifDrawable.seekToFrameAndGet(i)
                    val width = bitmap.width
                    val height = bitmap.height

                    val scaleWidth = (512.0 / width).toFloat()
                    val scaleHeight = (512.0 / height).toFloat()

                    val matrix = Matrix()
                    matrix.postScale(scaleWidth, scaleHeight)
                    val resizeBitmap = Bitmap.createBitmap(bitmap, 0, 0, width, height, matrix, true)
                    val frameDuration = gifDrawable.getFrameDuration(i).toLong()
                    time += frameDuration
                    webPAnimEncoder.addFrame(time, resizeBitmap)
                }

                webPAnimEncoder.assemble(BaseApp.mContext, gifDrawable.duration.toLong(), Uri.fromFile(out))
                webPAnimEncoder.release()
zubinxiong commented 1 year ago

image

UdaraWanasinghe commented 1 year ago

Try changing from WebPConfig.COMPRESSION_LOSSY to WebPConfig.COMPRESSION_LOSSLESS Dispose is an internally determined parameter by the encoder. See WEBP container specification for more information https://developers.google.com/speed/webp/docs/riff_container#animation

zubinxiong commented 1 year ago
UdaraWanasinghe commented 1 year ago

Save the returned bitmaps and verifying them for any distortions or use different gif decoder like Glide. https://github.com/bumptech/glide

val target = Glide.with(context)
    .asGif()
    .load(srcUri)
    .submit()
val drawable = target.get()
val gifState = drawable.constantState ?: throw NullPointerException("GifState is null")
val frameLoaderField = gifState.javaClass.getDeclaredField("frameLoader")
frameLoaderField.isAccessible = true
val frameLoader = frameLoaderField[gifState]
val decoderField = frameLoader.javaClass.getDeclaredField("gifDecoder")
decoderField.isAccessible = true
val gifDecoder = decoderField[frameLoader] as StandardGifDecoder

for (i in 0 until gifDecoder.frameCount) {
    gifDecoder.advance()
    val bitmap = gifDecoder.nextFrame
}
zubinxiong commented 1 year ago