显示长位图

时间:2019-01-05 16:31:21

标签: android bitmap android-glide

我需要加载一个非常长的(约15K px)黑白位图,该位图具有屏幕宽度。

我尝试了几种方法,最好的方法似乎是使用Glide

private fun loadGlideScreenWideCompress(context: Context, imageView: AppCompatImageView) {
    imageView.adjustViewBounds = true
    val params = LayoutParams(MATCH_PARENT, WRAP_CONTENT)
    imageView.layoutParams = params

    GlideApp.with(context)
            .load(imageRes)
            .encodeFormat(Bitmap.CompressFormat.WEBP)
            .diskCacheStrategy(DiskCacheStrategy.ALL)
            .into(imageView)
}

问题是-图像质量丢失。图片模糊不清,文字不可读。

我尝试使用BitmapRegionDecoder。我没有看到质量损失或内存问题。但是,它仅解码图像的一部分。我不太了解如何使用它:在滚动事件下解码下一部分?这将很难实现。测量可绘制高度,并将完整高度传递到BitmapRegionDecoder上,直觉感觉是错误的,因为这是解码器仅用于区域。

另一个问题是图像很大,我需要它适合所有屏幕尺寸。如果我采用最大可能的大小然后进行缩放,则需要执行昂贵的位图创建操作并潜在地阻塞主线程。

常规方法不起作用,并给出OOM例外:

    val bitmap = BitmapFactory.Options().run {
        inJustDecodeBounds = true
        inPreferredConfig = Bitmap.Config.ALPHA_8
        inDensity = displayMetrics.densityDpi
        BitmapFactory.decodeResource(context.resources, imageRes, this)
    }
    imageView.scaleType = ImageView.ScaleType.FIT_CENTER
    imageView.setImageBitmap(bitmap)

代码按比例缩小:

val res = context.resources
    val display = res.displayMetrics
    val dr = res.getDrawable(imageRes!!)
    val original = (dr as BitmapDrawable).bitmap

    val scale = original.width / display.widthPixels
    val scaledBitmap = BitmapDrawable(res, Bitmap.createScaledBitmap(
            original,
            display.widthPixels,
            original.height / scale,
            true
    ))
    imageView.adjustViewBounds = true

    val bos = ByteArrayOutputStream()
    scaledBitmap.bitmap.compress(CompressFormat.WEBP, 100, bos)
    val decoder = BitmapRegionDecoder.newInstance(
            ByteArrayInputStream(bos.toByteArray()),
            false
    )

    val rect = Rect(
            0,
            0,
            scaledBitmap.intrinsicWidth,
            scaledBitmap.intrinsicHeight
    )
    val bitmapFactoryOptions = BitmapFactory.Options()
    bitmapFactoryOptions.inPreferredConfig = Bitmap.Config.ALPHA_8;
    bitmapFactoryOptions.inDensity = display.densityDpi;
    val bmp = decoder.decodeRegion(rect, bitmapFactoryOptions);
    imageView.setImageBitmap(bmp)

问题是:在这种情况下最好的方法是什么?如何正确使用BitmapRegionDecoder

0 个答案:

没有答案