Capture: reduce conversions between Mat/Bitmap/ByteArray

This commit is contained in:
Pierre-Yves Nicolas
2026-03-24 10:05:37 +01:00
parent ceceaf8792
commit 40314def4e
6 changed files with 24 additions and 40 deletions

View File

@@ -109,7 +109,7 @@ class MainViewModel(val imageRepository: ImageRepository, launchMode: LaunchMode
fun handleImageCaptured(capturedPage: CapturedPage) {
viewModelScope.launch {
imageRepository.add(
compressJpeg(capturedPage.page, 75),
capturedPage.pageJpeg,
compressJpeg(capturedPage.source, 90),
capturedPage.metadata,
)

View File

@@ -18,7 +18,7 @@ package org.fairscan.app.domain
import android.graphics.Bitmap
data class CapturedPage(
val page: Bitmap,
val pageJpeg: ByteArray,
val source: Bitmap,
val metadata: PageMetadata,
)

View File

@@ -285,7 +285,7 @@ private fun CameraScreenScaffold(
)
}
if (cameraUiState.captureState is CaptureState.CapturePreview) {
val page = cameraUiState.captureState.capturedPage.page
val page = bitmap(cameraUiState.captureState.capturedPage.pageJpeg)
CapturedImage(page.asImageBitmap(), thumbnailCoords)
}
}
@@ -533,10 +533,10 @@ fun CameraScreenPreviewWithProcessedImage() {
val p = Point(0 , 0)
val quad = Quad(p, p, p, p)
ScreenPreview(CaptureState.CapturePreview(
debugImage("uncropped/img01.jpg"),
bitmap(debugImage("uncropped/img01.jpg")),
CapturedPage(
debugImage("gallica.bnf.fr-bpt6k5530456s-1.jpg"),
debugImage("gallica.bnf.fr-bpt6k5530456s-1.jpg"),
bitmap(debugImage("gallica.bnf.fr-bpt6k5530456s-1.jpg")),
PageMetadata(quad, R0, false))))
}
@@ -559,7 +559,7 @@ private fun ScreenPreview(captureState: CaptureState, rotationDegrees: Float = 0
contentAlignment = Alignment.TopCenter
) {
Image(
debugImage("uncropped/img01.jpg").asImageBitmap(),
bitmap(debugImage("uncropped/img01.jpg")).asImageBitmap(),
modifier=Modifier.rotate(rotationDegrees),
contentDescription = null
)
@@ -591,9 +591,9 @@ private fun ScreenPreview(captureState: CaptureState, rotationDegrees: Float = 0
}
@Composable
private fun debugImage(imgName: String): Bitmap {
private fun debugImage(imgName: String): ByteArray {
val context = LocalContext.current
return context.assets.open(imgName).use { input ->
BitmapFactory.decodeStream(input)
}
return context.assets.open(imgName).readBytes()
}
private fun bitmap(jpeg: ByteArray): Bitmap = BitmapFactory.decodeByteArray(jpeg, 0, jpeg.size)

View File

@@ -37,6 +37,7 @@ import org.fairscan.imageprocessing.ImageSize
import org.fairscan.imageprocessing.Mask
import org.fairscan.imageprocessing.Quad
import org.fairscan.imageprocessing.detectDocumentQuad
import org.fairscan.imageprocessing.encodeJpeg
import org.fairscan.imageprocessing.extractDocument
import org.fairscan.imageprocessing.isColoredDocument
import org.fairscan.imageprocessing.scaledTo
@@ -218,27 +219,14 @@ fun extractDocumentFromBitmap(
val isColored = isColoredDocument(bgr, mask, quad)
val maxPixels = ExportQuality.BALANCED.maxPixels
val page = extractDocument(bgr, quad, rotationDegrees, isColored, maxPixels)
val outBgr = page
val pageJpeg = encodeJpeg(page, ExportQuality.BALANCED.jpegQuality)
bgr.release()
val outBitmap = toBitmap(outBgr)
outBgr.release()
page.release()
val normalizedQuad = quad.scaledTo(source.width, source.height, 1, 1)
val baseRotation = Rotation.fromDegrees(rotationDegrees)
val metadata = PageMetadata(normalizedQuad, baseRotation, isColored)
return CapturedPage(outBitmap, source, metadata)
}
fun toBitmap(bgr: Mat): Bitmap {
require(bgr.type() == CvType.CV_8UC3)
val rgba = Mat()
Imgproc.cvtColor(bgr, rgba, Imgproc.COLOR_BGR2RGBA)
val bmp = createBitmap(bgr.cols(), bgr.rows(), Bitmap.Config.ARGB_8888)
Utils.matToBitmap(rgba, bmp)
rgba.release()
return bmp
return CapturedPage(pageJpeg, source, metadata)
}
fun rotateBitmap(source: Bitmap, angle: Float): Bitmap {