tranforming images for adaptive shortcuts within glides transformations
- avoid creating new bitmaps each time the room list changes
This commit is contained in:
parent
eeb9785651
commit
9f44975b4a
@ -0,0 +1,54 @@
|
|||||||
|
/*
|
||||||
|
* Copyright (c) 2022 New Vector Ltd
|
||||||
|
*
|
||||||
|
* Licensed under the Apache License, Version 2.0 (the "License");
|
||||||
|
* you may not use this file except in compliance with the License.
|
||||||
|
* You may obtain a copy of the License at
|
||||||
|
*
|
||||||
|
* http://www.apache.org/licenses/LICENSE-2.0
|
||||||
|
*
|
||||||
|
* Unless required by applicable law or agreed to in writing, software
|
||||||
|
* distributed under the License is distributed on an "AS IS" BASIS,
|
||||||
|
* WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied.
|
||||||
|
* See the License for the specific language governing permissions and
|
||||||
|
* limitations under the License.
|
||||||
|
*/
|
||||||
|
|
||||||
|
package im.vector.app.features.home
|
||||||
|
|
||||||
|
import android.graphics.Bitmap
|
||||||
|
import android.graphics.Canvas
|
||||||
|
import com.bumptech.glide.load.engine.bitmap_recycle.BitmapPool
|
||||||
|
import com.bumptech.glide.load.resource.bitmap.BitmapTransformation
|
||||||
|
import com.bumptech.glide.util.Util
|
||||||
|
import java.nio.ByteBuffer
|
||||||
|
import java.security.MessageDigest
|
||||||
|
|
||||||
|
private const val ADAPTIVE_TRANSFORMATION_ID = "adaptive-icon-transform"
|
||||||
|
private val ID_BYTES = ADAPTIVE_TRANSFORMATION_ID.toByteArray()
|
||||||
|
|
||||||
|
class AdaptiveIconTransformation(private val adaptiveIconSize: Int, private val adaptiveIconOuterSides: Float) : BitmapTransformation() {
|
||||||
|
|
||||||
|
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
|
||||||
|
messageDigest.update(ID_BYTES)
|
||||||
|
messageDigest.update(ByteBuffer.allocate(4).putInt(adaptiveIconSize).putFloat(adaptiveIconOuterSides).array())
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun transform(pool: BitmapPool, toTransform: Bitmap, outWidth: Int, outHeight: Int): Bitmap {
|
||||||
|
val insetBmp = Bitmap.createBitmap(adaptiveIconSize, adaptiveIconSize, Bitmap.Config.ARGB_8888)
|
||||||
|
val canvas = Canvas(insetBmp)
|
||||||
|
canvas.drawBitmap(toTransform, adaptiveIconOuterSides, adaptiveIconOuterSides, null)
|
||||||
|
canvas.setBitmap(null)
|
||||||
|
return insetBmp
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun equals(other: Any?): Boolean {
|
||||||
|
return if (other is AdaptiveIconTransformation) {
|
||||||
|
other.adaptiveIconSize == adaptiveIconSize && other.adaptiveIconOuterSides == adaptiveIconOuterSides
|
||||||
|
} else {
|
||||||
|
false
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
override fun hashCode() = Util.hashCode(ADAPTIVE_TRANSFORMATION_ID.hashCode(), Util.hashCode(adaptiveIconSize, Util.hashCode(adaptiveIconOuterSides)))
|
||||||
|
}
|
@ -26,6 +26,7 @@ import androidx.core.graphics.drawable.toBitmap
|
|||||||
import com.amulyakhare.textdrawable.TextDrawable
|
import com.amulyakhare.textdrawable.TextDrawable
|
||||||
import com.bumptech.glide.load.MultiTransformation
|
import com.bumptech.glide.load.MultiTransformation
|
||||||
import com.bumptech.glide.load.Transformation
|
import com.bumptech.glide.load.Transformation
|
||||||
|
import com.bumptech.glide.load.engine.DiskCacheStrategy
|
||||||
import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
import com.bumptech.glide.load.resource.bitmap.CenterCrop
|
||||||
import com.bumptech.glide.load.resource.bitmap.CircleCrop
|
import com.bumptech.glide.load.resource.bitmap.CircleCrop
|
||||||
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
import com.bumptech.glide.load.resource.bitmap.RoundedCorners
|
||||||
@ -157,7 +158,26 @@ class AvatarRenderer @Inject constructor(private val activeSessionHolder: Active
|
|||||||
fun shortcutDrawable(glideRequests: GlideRequests, matrixItem: MatrixItem, iconSize: Int): Bitmap {
|
fun shortcutDrawable(glideRequests: GlideRequests, matrixItem: MatrixItem, iconSize: Int): Bitmap {
|
||||||
return glideRequests
|
return glideRequests
|
||||||
.asBitmap()
|
.asBitmap()
|
||||||
.let {
|
.avatarOrText(matrixItem, iconSize)
|
||||||
|
.apply(RequestOptions.centerCropTransform())
|
||||||
|
.submit(iconSize, iconSize)
|
||||||
|
.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
@AnyThread
|
||||||
|
@Throws
|
||||||
|
fun adaptiveShortcutDrawable(glideRequests: GlideRequests, matrixItem: MatrixItem, iconSize: Int, adaptiveIconSize: Int, adaptiveIconOuterSides: Float): Bitmap {
|
||||||
|
return glideRequests
|
||||||
|
.asBitmap()
|
||||||
|
.avatarOrText(matrixItem, iconSize)
|
||||||
|
.transform(CenterCrop(), AdaptiveIconTransformation(adaptiveIconSize, adaptiveIconOuterSides))
|
||||||
|
.diskCacheStrategy(DiskCacheStrategy.RESOURCE)
|
||||||
|
.submit(adaptiveIconSize, adaptiveIconSize)
|
||||||
|
.get()
|
||||||
|
}
|
||||||
|
|
||||||
|
private fun GlideRequest<Bitmap>.avatarOrText(matrixItem: MatrixItem, iconSize: Int): GlideRequest<Bitmap> {
|
||||||
|
return this.let {
|
||||||
val resolvedUrl = resolvedUrl(matrixItem.avatarUrl)
|
val resolvedUrl = resolvedUrl(matrixItem.avatarUrl)
|
||||||
if (resolvedUrl != null) {
|
if (resolvedUrl != null) {
|
||||||
it.load(resolvedUrl)
|
it.load(resolvedUrl)
|
||||||
@ -171,9 +191,6 @@ class AvatarRenderer @Inject constructor(private val activeSessionHolder: Active
|
|||||||
.toBitmap(width = iconSize, height = iconSize))
|
.toBitmap(width = iconSize, height = iconSize))
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
.apply(RequestOptions.centerCropTransform())
|
|
||||||
.submit(iconSize, iconSize)
|
|
||||||
.get()
|
|
||||||
}
|
}
|
||||||
|
|
||||||
@UiThread
|
@UiThread
|
||||||
|
@ -19,7 +19,6 @@ package im.vector.app.features.home
|
|||||||
import android.content.Context
|
import android.content.Context
|
||||||
import android.content.pm.ShortcutInfo
|
import android.content.pm.ShortcutInfo
|
||||||
import android.graphics.Bitmap
|
import android.graphics.Bitmap
|
||||||
import android.graphics.Canvas
|
|
||||||
import android.os.Build
|
import android.os.Build
|
||||||
import androidx.annotation.WorkerThread
|
import androidx.annotation.WorkerThread
|
||||||
import androidx.core.content.pm.ShortcutInfoCompat
|
import androidx.core.content.pm.ShortcutInfoCompat
|
||||||
@ -61,7 +60,12 @@ class ShortcutCreator @Inject constructor(
|
|||||||
fun create(roomSummary: RoomSummary, rank: Int = 1): ShortcutInfoCompat {
|
fun create(roomSummary: RoomSummary, rank: Int = 1): ShortcutInfoCompat {
|
||||||
val intent = RoomDetailActivity.shortcutIntent(context, roomSummary.roomId)
|
val intent = RoomDetailActivity.shortcutIntent(context, roomSummary.roomId)
|
||||||
val bitmap = try {
|
val bitmap = try {
|
||||||
avatarRenderer.shortcutDrawable(GlideApp.with(context), roomSummary.toMatrixItem(), iconSize)
|
val glideRequests = GlideApp.with(context)
|
||||||
|
val matrixItem = roomSummary.toMatrixItem()
|
||||||
|
when (useAdaptiveIcon) {
|
||||||
|
true -> avatarRenderer.adaptiveShortcutDrawable(glideRequests, matrixItem, iconSize, adaptiveIconSize, adaptiveIconOuterSides.toFloat())
|
||||||
|
false -> avatarRenderer.shortcutDrawable(glideRequests, matrixItem, iconSize)
|
||||||
|
}
|
||||||
} catch (failure: Throwable) {
|
} catch (failure: Throwable) {
|
||||||
null
|
null
|
||||||
}
|
}
|
||||||
@ -83,11 +87,7 @@ class ShortcutCreator @Inject constructor(
|
|||||||
|
|
||||||
private fun Bitmap.toProfileImageIcon(): IconCompat {
|
private fun Bitmap.toProfileImageIcon(): IconCompat {
|
||||||
return if (useAdaptiveIcon) {
|
return if (useAdaptiveIcon) {
|
||||||
val insetBmp = Bitmap.createBitmap(adaptiveIconSize, adaptiveIconSize, Bitmap.Config.ARGB_8888)
|
IconCompat.createWithAdaptiveBitmap(this)
|
||||||
val canvas = Canvas(insetBmp)
|
|
||||||
canvas.drawBitmap(this, adaptiveIconOuterSides.toFloat(), adaptiveIconOuterSides.toFloat(), null)
|
|
||||||
|
|
||||||
IconCompat.createWithAdaptiveBitmap(insetBmp)
|
|
||||||
} else {
|
} else {
|
||||||
IconCompat.createWithBitmap(this)
|
IconCompat.createWithBitmap(this)
|
||||||
}
|
}
|
||||||
|
Loading…
x
Reference in New Issue
Block a user