Fix crash when drawing > 100 MB bitmaps

This commit is contained in:
FooIbar committed 2024-09-03 19:03:54 +08:00
1 parent 380554bd19
commit c60b14998a
2 files changed
+49 -3

No files matched your search

@@ -0,0 +1,48 @@
package com.hippo.ehviewer.ui.reader
import android.graphics.Bitmap
import android.graphics.Matrix
import android.graphics.Paint
import androidx.compose.ui.graphics.drawscope.DrawScope
import androidx.compose.ui.graphics.drawscope.drawIntoCanvas
import androidx.compose.ui.graphics.nativeCanvas
import androidx.compose.ui.graphics.painter.Painter
import androidx.compose.ui.unit.IntOffset
import androidx.compose.ui.unit.IntSize
import androidx.compose.ui.unit.toOffset
import androidx.compose.ui.unit.toSize
class BitmapPainter(
private val image: Bitmap,
srcOffset: IntOffset = IntOffset.Zero,
srcSize: IntSize = IntSize(image.width, image.height),
) : Painter() {
private val offset = (-srcOffset).toOffset()
private val srcSize = srcSize.toSize()
private val matrix = Matrix()
override fun DrawScope.onDraw() = drawIntoCanvas {
// Use the overload that takes a `Matrix` to bypass the 100 MB size limit
it.nativeCanvas.drawBitmap(
image,
matrix.apply {
setTranslate(offset.x, offset.y)
postScale(size.width / srcSize.width, size.height / srcSize.height)
},
bitmapPaint,
)
}
override val intrinsicSize get() = srcSize
companion object {
private val bitmapPaint = Paint().apply {
isAntiAlias = true
isFilterBitmap = true
isDither = true
}
}
}
@@ -20,8 +20,6 @@ import androidx.compose.ui.Alignment
import androidx.compose.ui.Modifier
import androidx.compose.ui.graphics.ColorFilter
import androidx.compose.ui.graphics.ColorMatrix
import androidx.compose.ui.graphics.asImageBitmap
import androidx.compose.ui.graphics.painter.BitmapPainter
import androidx.compose.ui.layout.ContentScale
import androidx.compose.ui.res.stringResource
import androidx.compose.ui.text.style.TextAlign
@@ -114,7 +112,7 @@ fun PagerItem(
private fun Image.toPainter() = when (val image = innerImage) {
is BitmapImage -> BitmapPainter(
image = image.bitmap.asImageBitmap(),
image = image.bitmap,
srcOffset = rect.topLeft,
srcSize = rect.size,
)