gpt4 book ai didi

android - 使用 Glide 4.11 时出现 "trying to use a recycled bitmap"崩溃,转换会导致此问题吗?

转载 作者:行者123 更新时间:2023-12-02 12:49:53 25 4
gpt4 key购买 nike

我知道已经有很多与“尝试使用回收位图”崩溃相关的问题,但没有一个对我有帮助。

详细信息:

  • 在这个项目的任何地方都没有调用 Bitmap.recycle()
  • 所有图片均使用 Glide (4.11.0) 加载
  • Glide 调用都很简单,而且不使用占位符
  • 崩溃似乎是在切换 fragment 时随机发生的

我唯一能想到的就是转换。此项目中只有 2 个转换。

CircleTransformation(将图像剪辑为具有自定义半径的圆):

class CircleTransformation(private val radius: Float) : BitmapTransformation() {
companion object {
private const val ID = "com.project.transformation.circle"
private val ID_BYTES: ByteArray = ID.toByteArray()
}

public override fun transform(pool: BitmapPool, source: Bitmap, outWidth: Int, outHeight: Int): Bitmap {
val paint = Paint()
paint.isAntiAlias = true
paint.shader = BitmapShader(source, Shader.TileMode.CLAMP, Shader.TileMode.CLAMP)

val halfWidth = source.width / 2f
val output = Bitmap.createBitmap(source.width, source.height, Bitmap.Config.ARGB_8888)
val canvas = Canvas(output)
canvas.drawCircle(
halfWidth,
(source.height / 2).toFloat(),
halfWidth * radius,
paint
)
return output
}

// Caching helpers
override fun equals(other: Any?): Boolean {
return other is CircleTransformation && other.hashCode() == hashCode()
}
override fun hashCode(): Int {
return ID.hashCode()
}
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
messageDigest.update(ID_BYTES)
}
}

和 ClipWhiteTransformation(从图像中删除白色边框):

class ClipWhiteTransformation() : BitmapTransformation() {
companion object {
private const val ID = "com.project.transformation.clipWhite"
private val ID_BYTES: ByteArray = ID.toByteArray()

// Config
const val white = 253 // White pixel, if all channels are equal or greater than this
const val transparent = 50 // Transparent pixel, if Less than this
}

public override fun transform(pool: BitmapPool, source: Bitmap, outWidth: Int, outHeight: Int): Bitmap {
val width = source.width - 1
val height = source.height - 1
val halfX = width / 2
val halfY = height / 2
var startY = 0


// Left Margin
var left = 0
for (x in 0 until halfX) {
val pixel = source.getPixel(x, halfY)

// Transparent?
if (Color.alpha(pixel) < transparent) continue

// Not white?
if (Color.red(pixel) < white || Color.green(pixel) < white || Color.blue(pixel) < white) {
left = x
if (x > 2) {
startY = 2
}
break
}
}

// Right Margin
var right = 0
for (x in 0 until halfX) {
val pixel = source.getPixel(width - x, halfY)

// Transparent?
if (Color.alpha(pixel) < transparent) continue

// Not white?
if (Color.red(pixel) < white || Color.green(pixel) < white || Color.blue(pixel) < white) {
right = x
if (x > 2) {
startY = 2
}
break
}
}

// Top Margin
var top = 0
for (y in startY until halfY) {
val pixel = source.getPixel(halfX, y)

// Transparent?
if (Color.alpha(pixel) < transparent) continue

// Not white?
if (Color.red(pixel) < white || Color.green(pixel) < white || Color.blue(pixel) < white) {
top = y
break
}
}

// Bottom Margin
var bottom = 0
for (y in startY until halfY) {
val pixel = source.getPixel(halfX, height - y)

// Transparent?
if (Color.alpha(pixel) < transparent) continue

// Not white?
if (Color.red(pixel) < white || Color.green(pixel) < white || Color.blue(pixel) < white) {
bottom = y
break
}
}

// Clip, scale and return
val newWidth = width - (left + right)
val newHeight = height - (top + bottom)
val scale = if (abs(newWidth - outWidth) > abs(newHeight - outHeight)) outWidth / newWidth.toFloat() else outHeight / newHeight.toFloat()
val matrix = Matrix().apply { setScale(scale, scale) }
return Bitmap.createBitmap(source, left, top, newWidth, newHeight, matrix, false)
}



// Caching helpers
override fun equals(other: Any?): Boolean {
return other is ClipWhiteTransformation && other.hashCode() == hashCode()
}
override fun hashCode(): Int {
return ID.hashCode()
}
override fun updateDiskCacheKey(messageDigest: MessageDigest) {
messageDigest.update(ID_BYTES)
}
}

最初使用的是 BitmapPool,删除它并没有阻止崩溃。

顺便说一句,这是用于加载图像的扩展:

fun ImageView.setURL(url: String, 
@DrawableRes error: Int? = null,
@DrawableRes placeholder: Int? = null,
size: Int? = null,
options: ((RequestBuilder<Drawable>) -> Unit)? = null,
completion: ((resource: Drawable?) -> Unit)? = null) {

// No URL, use Placeholder if exists, if not, use the error image
if (url.isEmpty()) {
placeholder?.also{ setImageResource(it) } ?: run { error?.also{ setImageResource(it) } }
return
}

Glide.with(applicationInstance) // (I'm using an application instance directly here)
.load(url).apply {
completion?.also { completion ->
this.listener(object : RequestListener<Drawable> {
override fun onLoadFailed(e: GlideException?, model: Any?, target: Target<Drawable>?, isFirstResource: Boolean): Boolean {
completion(null)
return false
}
override fun onResourceReady(resource: Drawable?, model: Any?, target: Target<Drawable>?, dataSource: DataSource?, isFirstResource: Boolean): Boolean {
completion(resource)
return false
}
})
}
}
.apply { size?.also { this.override(it)} }
.apply { options?.invoke(this) }
.placeholder(placeholder ?: 0)
.error(error ?: 0)
.transition(DrawableTransitionOptions.withCrossFade(350))
.into(this)
}

很抱歉在这里粘贴了这么多代码(希望它对某人有用)。这些转换或加载程序会导致崩溃吗?

最佳答案

塑造(circle/square/oval)你的形象你不需要改变你的形象。MaterialDesign 引入了 ShapeableImageView,它可以让您在运行时塑造图像,还可以添加带颜色的边框。

  1. 添加母系依赖:

    implementation 'com.google.android.material:material:1.3.0-alpha01'
  2. 在您的 xyz.xml 中添加 shapeableImageView:

    <com.google.android.material.imageview.ShapeableImageView
    android:id="@+id/imgStudent"
    android:layout_width="100dp"
    android:layout_height="100dp"
    app:shapeAppearanceOverlay="@style/circleImageView"
    android:padding="2dp"
    app:strokeColor="@color/white"
    app:strokeWidth="5dp"
    android:scaleType="centerCrop"
    android:adjustViewBounds="true"
    tools:srcCompat="@drawable/ic_kid_placeholder"
    />
  3. 在 res/values/style.xml 文件中添加样式

    <style name="circleImageView" parent="">
    <item name="cornerFamily">rounded</item>
    <item name="cornerSize">50%</item>
    <item name="android:shadowRadius">100</item>
    <item name="android:shadowColor">@color/gray</item>
    <item name="backgroundOverlayColorAlpha">12</item>
    </style>

最后用 glide 载入你的图片。

关于android - 使用 Glide 4.11 时出现 "trying to use a recycled bitmap"崩溃,转换会导致此问题吗?,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/62989167/

25 4 0
Copyright 2021 - 2024 cfsdn All Rights Reserved 蜀ICP备2022000587号
广告合作:1813099741@qq.com 6ren.com