Skip to content

Commit c392a07

Browse files
authored
feat: add support for animated AVIF images (#637)
Refs: #621
1 parent 152945e commit c392a07

File tree

5 files changed

+19
-6
lines changed

5 files changed

+19
-6
lines changed

app/build.gradle.kts

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -154,6 +154,7 @@ dependencies {
154154
implementation(libs.androidx.swiperefreshlayout)
155155
implementation(libs.awebp)
156156
implementation(libs.apng)
157+
implementation(libs.avif)
157158
implementation(libs.avif.integration)
158159
implementation(libs.jxl.integration)
159160
implementation(libs.okio)

app/src/main/kotlin/org/fossify/gallery/extensions/Context.kt

Lines changed: 0 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -698,7 +698,6 @@ fun Context.loadImageBase(
698698
}
699699

700700
// animation is only supported without rounded corners and the file must be a GIF or WEBP.
701-
// Glide doesn't support animated AVIF: https://bumptech.github.io/glide/int/avif.html
702701
if (animate && roundCorners == ROUNDED_CORNERS_NONE && (path.isGif() || path.isWebP())) {
703702
// this is required to make glide cache aware of changes
704703
options.decode(Drawable::class.java)

app/src/main/kotlin/org/fossify/gallery/fragments/PhotoFragment.kt

Lines changed: 12 additions & 1 deletion
Original file line numberDiff line numberDiff line change
@@ -44,6 +44,7 @@ import com.davemorrissey.labs.subscaleview.ImageDecoder
4444
import com.davemorrissey.labs.subscaleview.ImageRegionDecoder
4545
import com.davemorrissey.labs.subscaleview.SubsamplingScaleImageView
4646
import com.github.penfeizhou.animation.apng.APNGDrawable
47+
import com.github.penfeizhou.animation.avif.AVIFDrawable
4748
import com.github.penfeizhou.animation.webp.WebPDrawable
4849
import com.squareup.picasso.Callback
4950
import com.squareup.picasso.Picasso
@@ -348,7 +349,9 @@ class PhotoFragment : ViewPagerFragment() {
348349
super.setMenuVisibility(menuVisible)
349350
mIsFragmentVisible = menuVisible
350351
if (mWasInit) {
351-
if (!mMedium.isGIF() && !mMedium.isWebP() && !mMedium.isApng()) {
352+
val isAnimatedContent =
353+
mMedium.isGIF() || mMedium.isApng() || mMedium.isAvif() || mMedium.isWebP()
354+
if (isAnimatedContent) {
352355
photoFragmentVisibilityChanged(menuVisible)
353356
}
354357
}
@@ -419,6 +422,7 @@ class PhotoFragment : ViewPagerFragment() {
419422
mMedium.isGIF() -> loadGif()
420423
mMedium.isSVG() -> loadSVG()
421424
mMedium.isApng() -> loadAPNG()
425+
mMedium.isAvif() -> loadAVIF()
422426
else -> loadBitmap()
423427
}
424428
}
@@ -465,6 +469,13 @@ class PhotoFragment : ViewPagerFragment() {
465469
}
466470
}
467471

472+
private fun loadAVIF() {
473+
if (context != null) {
474+
val drawable = AVIFDrawable.fromFile(mMedium.path)
475+
binding.gesturesView.setImageDrawable(drawable)
476+
}
477+
}
478+
468479
private fun loadBitmap(addZoomableView: Boolean = true) {
469480
if (context == null) {
470481
return

app/src/main/kotlin/org/fossify/gallery/models/Medium.kt

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -52,6 +52,8 @@ data class Medium(
5252

5353
fun isApng() = name.isApng()
5454

55+
fun isAvif() = name.endsWith(".avif", true) // switch to commons extension.
56+
5557
fun isHidden() = name.startsWith('.')
5658

5759
fun isHeic() = name.lowercase(Locale.getDefault()).endsWith(".heic") || name.lowercase(Locale.getDefault()).endsWith(".heif")

gradle/libs.versions.toml

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -20,8 +20,7 @@ gradlePlugins-agp = "8.11.1"
2020
#Other
2121
androidGifDrawable = "1.2.29"
2222
androidImageCropper = "4.6.0"
23-
apng = "3.0.5"
24-
awebp = "3.0.5"
23+
animationAndroid = "3.0.5"
2524
glideCompiler = "5.0.3"
2625
zjupureWebpdecoder = "2.7.4.16.0"
2726
jxlDecoder = "2.3.0.1"
@@ -65,8 +64,9 @@ androidphotofilters = { module = "com.github.naveensingh:androidphotofilters", v
6564
okhttp = { module = "com.squareup.okhttp3:okhttp", version.ref = "okhttp" }
6665
okio = { module = "com.squareup.okio:okio", version.ref = "okio" }
6766
sanselan = { module = "org.apache.sanselan:sanselan", version.ref = "sanselan" }
68-
apng = { module = "com.github.penfeizhou.android.animation:apng", version.ref = "apng" }
69-
awebp = { module = "com.github.penfeizhou.android.animation:awebp", version.ref = "awebp" }
67+
apng = { module = "com.github.penfeizhou.android.animation:apng", version.ref = "animationAndroid" }
68+
awebp = { module = "com.github.penfeizhou.android.animation:awebp", version.ref = "animationAndroid" }
69+
avif = { module = "com.github.penfeizhou.android.animation:avif", version.ref = "animationAndroid" }
7070
glide-compiler = { module = "com.github.bumptech.glide:ksp", version.ref = "glideCompiler" }
7171
zjupure-webpdecoder = { module = "com.github.zjupure:webpdecoder", version.ref = "zjupureWebpdecoder" }
7272
picasso = { module = "com.squareup.picasso:picasso", version.ref = "picasso" }

0 commit comments

Comments
 (0)