Save generated avatar as files in cache for faster re-user and lower memory footprint

This commit is contained in:
Sylvain Berfini 2025-10-21 15:30:26 +02:00
parent 0e71a726c1
commit b0283043ee
4 changed files with 25 additions and 20 deletions

View file

@ -39,6 +39,7 @@ import org.linphone.utils.TimestampUtils
import androidx.core.net.toUri
import androidx.core.graphics.createBitmap
import kotlinx.coroutines.withContext
import org.linphone.utils.FileUtils.Companion.getFileStorageCacheDir
import java.io.File
class FileModel
@ -199,7 +200,8 @@ class FileModel
PdfRenderer.Page.RENDER_MODE_FOR_DISPLAY
)
val previewPath = FileUtils.storeBitmap(previewBitmap, fileName)
val file = getFileStorageCacheDir("$fileName.jpg", true)
val previewPath = FileUtils.storeBitmap(previewBitmap, file)
Log.i("$TAG Preview of PDF file [$path] available at [$previewPath]")
mediaPreview.postValue(previewPath)
mediaPreviewAvailable.postValue(true)
@ -226,7 +228,8 @@ class FileModel
MediaStore.Images.Thumbnails.MINI_KIND
)
if (previewBitmap != null) {
val previewPath = FileUtils.storeBitmap(previewBitmap, fileName)
val file = getFileStorageCacheDir("$fileName.jpg", true)
val previewPath = FileUtils.storeBitmap(previewBitmap, file)
Log.i("$TAG Preview of video file [$path] available at [$previewPath]")
mediaPreview.postValue(previewPath)
mediaPreviewAvailable.postValue(true)

View file

@ -64,7 +64,6 @@ import com.google.android.flexbox.FlexboxLayout
import org.linphone.BR
import org.linphone.R
import org.linphone.contacts.AbstractAvatarModel
import org.linphone.contacts.AvatarGenerator
import org.linphone.core.ConsolidatedPresence
import org.linphone.core.tools.Log
import org.linphone.ui.NotoSansFont
@ -449,14 +448,6 @@ fun ImageView.loadCallAvatarWithCoil(model: AbstractAvatarModel?) {
loadContactPictureWithCoil(this, model, size = size, textSize = initialsSize)
}
@UiThread
@BindingAdapter("coilInitials")
fun ImageView.loadInitialsAvatarWithCoil(initials: String?) {
val builder = AvatarGenerator(context)
builder.setInitials(initials.orEmpty())
load(builder.buildDrawable())
}
@SuppressLint("ResourceType")
private fun loadContactPictureWithCoil(
imageView: ImageView,
@ -508,7 +499,7 @@ private fun getErrorImageLoader(
R.drawable.inset_user_circle
}
} else {
ImageUtils.getGeneratedAvatar(context, size, textSize, initials)
ImageUtils.generatedAvatarIfNeededAndReturnPath(context, size, textSize, initials)
}
}

View file

@ -413,16 +413,20 @@ class FileUtils {
}
@AnyThread
fun storeBitmap(bitmap: Bitmap, fileName: String): String {
val path = getFileStorageCacheDir("$fileName.jpg", true)
FileOutputStream(path).use { outputStream ->
fun storeBitmap(bitmap: Bitmap, file: File): String {
val format = if (file.absolutePath.endsWith(".png")) {
Bitmap.CompressFormat.PNG
} else {
Bitmap.CompressFormat.JPEG
}
FileOutputStream(file).use { outputStream ->
bitmap.compress(
Bitmap.CompressFormat.JPEG,
format,
100,
outputStream
)
}
return path.absolutePath
return file.absolutePath
}
@AnyThread

View file

@ -27,7 +27,6 @@ import android.graphics.Paint
import android.graphics.PorterDuff
import android.graphics.PorterDuffXfermode
import android.graphics.Rect
import android.graphics.drawable.BitmapDrawable
import androidx.annotation.AnyThread
import androidx.annotation.WorkerThread
import java.io.FileNotFoundException
@ -41,7 +40,13 @@ class ImageUtils {
private const val TAG = "[Image Utils]"
@AnyThread
fun getGeneratedAvatar(context: Context, size: Int = 0, textSize: Int = 0, initials: String): BitmapDrawable {
fun generatedAvatarIfNeededAndReturnPath(context: Context, size: Int = 0, textSize: Int = 0, initials: String): String {
val generatedAvatarPath = FileUtils.getFileStorageCacheDir("$initials.png", overrideExisting = true)
if (generatedAvatarPath.exists()) {
val path = generatedAvatarPath.absolutePath
return path
}
val builder = AvatarGenerator(context)
builder.setInitials(initials)
if (size > 0) {
@ -52,7 +57,9 @@ class ImageUtils {
if (textSize > 0) {
builder.setTextSize(AppUtils.getDimension(textSize))
}
return builder.buildDrawable()
val bitmap = builder.buildBitmap(true)
val path = FileUtils.storeBitmap(bitmap, generatedAvatarPath)
return path
}
@WorkerThread