Skip to content

Canvas: trying to use a recycled bitmap #17

@Odaym

Description

@Odaym

Hi, great work on the library, works well and is super easy to use. I am facing a rare issue I would say, it happens sometimes when I press on the Rotate Left/Right buttons of the cropper view, below is the stacktrace and the place of call

 FATAL EXCEPTION: main
 Process: com.saltserv.booksum, PID: 12181
 java.lang.RuntimeException: Canvas: trying to use a recycled bitmap android.graphics.Bitmap@69de664
 	at android.graphics.BaseCanvas.throwIfCannotDraw(BaseCanvas.java:66)
 	at android.graphics.RecordingCanvas.throwIfCannotDraw(RecordingCanvas.java:277)
 	at android.graphics.BaseRecordingCanvas.drawBitmap(BaseRecordingCanvas.java:88)
 	at androidx.compose.ui.graphics.AndroidCanvas.drawImageRect-HPBpro0(AndroidCanvas.android.kt:275)
 	at androidx.compose.ui.graphics.drawscope.CanvasDrawScope.drawImage-AZ2fEMs(CanvasDrawScope.kt:256)
 	at androidx.compose.ui.node.LayoutNodeDrawScope.drawImage-AZ2fEMs(Unknown Source:24)
 	at androidx.compose.ui.graphics.drawscope.DrawScope.drawImage-AZ2fEMs$default(DrawScope.kt:551)
 	at com.mr0xf00.easycrop.ui.CropperPreviewKt$CropperPreview$4.invoke(CropperPreview.kt:61)
 	at com.mr0xf00.easycrop.ui.CropperPreviewKt$CropperPreview$4.invoke(CropperPreview.kt:46)
 	at androidx.compose.ui.draw.DrawBackgroundModifier.draw(DrawModifier.kt:116)
 	at androidx.compose.ui.node.LayoutNodeDrawScope.drawDirect-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:105)
 	at androidx.compose.ui.node.LayoutNodeDrawScope.performDraw(LayoutNodeDrawScope.kt:76)
 	at androidx.compose.ui.node.LayoutNodeDrawScope.drawContent(LayoutNodeDrawScope.kt:55)
 	at androidx.compose.foundation.BackgroundNode.draw(Background.kt:159)
 	at androidx.compose.ui.node.LayoutNodeDrawScope.drawDirect-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:105)
 	at androidx.compose.ui.node.LayoutNodeDrawScope.draw-x_KDEd0$ui_release(LayoutNodeDrawScope.kt:86)
 	at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:364)
 	at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:353)
 	at androidx.compose.ui.node.LayoutModifierNodeCoordinator.performDraw(LayoutModifierNodeCoordinator.kt:176)
 	at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:361)
 	at androidx.compose.ui.node.NodeCoordinator.draw(NodeCoordinator.kt:353)
 	at androidx.compose.ui.node.LayoutNode.draw$ui_release(LayoutNode.kt:926)
 	at androidx.compose.ui.node.InnerNodeCoordinator.performDraw(InnerNodeCoordinator.kt:174)
 	at androidx.compose.ui.node.NodeCoordinator.drawContainedDrawModifiers(NodeCoordinator.kt:361)
 	at androidx.compose.ui.node.NodeCoordinator.access$drawContainedDrawModifiers(NodeCoordinator.kt:54)
 	at androidx.compose.ui.node.NodeCoordinator$drawBlock$1$1.invoke(NodeCoordinator.kt:383)
 	at androidx.compose.ui.node.NodeCoordinator$drawBlock$1$1.invoke(NodeCoordinator.kt:382)
 	at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2303)
 	at androidx.compose.runtime.snapshots.SnapshotStateObserver$ObservedScopeMap.observe(SnapshotStateObserver.kt:500)
 	at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:256)
 	at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:133)
 	at androidx.compose.ui.node.NodeCoordinator$drawBlock$1.invoke(NodeCoordinator.kt:382)
 	at androidx.compose.ui.node.NodeCoordinator$drawBlock$1.invoke(NodeCoordinator.kt:380)
 	at androidx.compose.ui.platform.RenderNodeApi29.record(RenderNodeApi29.android.kt:209)
 	at androidx.compose.ui.platform.RenderNodeLayer.updateDisplayList(RenderNodeLayer.android.kt:335)
 	at androidx.compose.ui.platform.AndroidComposeView.dispatchDraw(AndroidComposeView.android.kt:1236)
 	at android.view.View.draw(View.java:22353)
 	at android.view.View.updateDisplayListIfDirty(View.java:21226)
 	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4500)
 	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4473)
 	at android.view.View.updateDisplayListIfDirty(View.java:21186)
 	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4500)
 	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4473)
 	at android.view.View.updateDisplayListIfDirty(View.java:21186)
22:40:04.871  E  	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4500)
 	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4473)
 	at android.view.View.updateDisplayListIfDirty(View.java:21186)
 	at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4500)
 	at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4473)
 	at android.view.View.updateDisplayListIfDirty(View.java:21186)
 	at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:559)
 	at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:565)
 	at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:642)
 	at android.view.ViewRootImpl.draw(ViewRootImpl.java:4101)
 	at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3828)
 	at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3099)
 	at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1952)
 	at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8171)
 	at android.view.Choreographer$CallbackRecord.run(Choreographer.java:972)
 	at android.view.Choreographer.doCallbacks(Choreographer.java:796)
 	at android.view.Choreographer.doFrame(Choreographer.java:731)
 	at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:957)
 	at android.os.Handler.handleCallback(Handler.java:938)
 	at android.os.Handler.dispatchMessage(Handler.java:99)
 	at android.os.Looper.loop(Looper.java:223)
 	at android.app.ActivityThread.main(ActivityThread.java:7656)
 	at java.lang.reflect.Method.invoke(Native Method)
 	at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:592)
 	at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:947)

And this is where/how I call it:

val imageCropper = rememberImageCropper()
        val scope = rememberCoroutineScope()

        val cropState = imageCropper.cropState
        if (cropState != null) {
            ImageCropperDialog(state = cropState)
        }

        CameraScreen(
            scaffoldState = scaffoldState,
            onPhotoClicked = { bitmap, bookId ->
                scope.launch {
                    when (val result = imageCropper.crop(bmp = bitmap.asImageBitmap())) {
                        is CropResult.Cancelled -> {}
                        is CropError -> {}
                        is CropResult.Success -> {
                            navController.navigatePreviewSnippet(
                                result.bitmap.asAndroidBitmap(),
                                bookId
                            )
                        }
                    }
                }
            },
        )

This is definitely happening sometimes only, most of the time I don't think i can say it happens.

appreciate if you could help verify if this is from your end or not, i haven't tried anything yet, thanks!

Metadata

Metadata

Assignees

No one assigned

    Labels

    No labels
    No labels

    Projects

    No projects

    Milestone

    No milestone

    Relationships

    None yet

    Development

    No branches or pull requests

    Issue actions