Android View 转 Bitmap 兼容性记录

39 阅读1分钟

1、用com.blankj.utilcode.util 里面的 工具类 android 13 保存图片报错

val bitmap = ImageUtils.view2Bitmap(binding.saveQRCodeLayout)
return ImageUtils.save2Album(bitmap, Bitmap.CompressFormat.JPEG)
# [java.lang.IllegalStateException: Software rendering doesn't support hardware bitmaps](https://stackoverflow.com/questions/58314397/java-lang-illegalstateexception-software-rendering-doesnt-support-hardware-bit)

2、修复兼容性

stackoverflow.com/questions/5…

/**
 * https://stackoverflow.com/questions/58314397/java-lang-illegalstateexception-software-rendering-doesnt-support-hardware-bit
 * @receiver View
 * @param onBitmapReady Function1<Bitmap, Unit>
 * @param onBitmapError Function1<Exception, Unit>
 */
fun View.toBitmap( window: Window ,onBitmapReady: (Bitmap) -> Unit, onBitmapError: (Exception) -> Unit) {

    try {

        if (Build.VERSION.SDK_INT >= Build.VERSION_CODES.O) {

            val temporalBitmap = Bitmap.createBitmap(this.width, this.height, Bitmap.Config.ARGB_8888)

            // Above Android O, use PixelCopy due
            // https://stackoverflow.com/questions/58314397/
            //val window: Window = (this.context as Activity).window

            val location = IntArray(2)

            this.getLocationInWindow(location)

            val viewRectangle = Rect(location[0], location[1], location[0] + this.width, location[1] + this.height)

            val onPixelCopyListener: PixelCopy.OnPixelCopyFinishedListener = PixelCopy.OnPixelCopyFinishedListener { copyResult ->

                if (copyResult == PixelCopy.SUCCESS) {

                    onBitmapReady(temporalBitmap)
                } else {

                    error("Error while copying pixels, copy result: $copyResult")
                }
            }

            PixelCopy.request(window, viewRectangle, temporalBitmap, onPixelCopyListener, Handler(Looper.getMainLooper()))
        } else {

            val temporalBitmap = Bitmap.createBitmap(this.width, this.height, Bitmap.Config.RGB_565)

            val canvas = android.graphics.Canvas(temporalBitmap)

            this.draw(canvas)

            canvas.setBitmap(null)

            onBitmapReady(temporalBitmap)
        }

    } catch (exception: Exception) {

        onBitmapError(exception)
        exception.printStackTrace()
    }
}

Dialog

lifecycleScope.launch {
    var file :File? = null
    withContext(Dispatchers.IO){
        dialog?.window?.let {
            binding.saveQRCodeLayout.toBitmap(it,{ bitmap ->
                file = ImageUtils.save2Album(bitmap, Bitmap.CompressFormat.JPEG)
            },{

            })
        }
    }
    file?.let {
        dismissAllowingStateLoss()
        AppToast.showShort(Utils.getApp().getString(R.string.personal_saved_successfully))
    }
}

Actvitiy

lifecycleScope.launch {
    var file: File? = null
    withContext(Dispatchers.IO) {
        window?.let {
            binding.paymentQrCodeCL.toBitmap(window, { bitmap ->
                file = ImageUtils.save2Album(bitmap, Bitmap.CompressFormat.JPEG)
            }, {

            })
        }
    }
    file?.let {
        ToastUtils.showShort(getAppString(R.string.personal_saved_successfully))
    }
}