Code Monkey home page Code Monkey logo

compose-cropper's Introduction

I'm from Thrace. Currently developing Android projects with Jetpack Compose and answering Jetpack Compose questions on Stackoverflow with Thracian alias. Answered over 630 questions and top 3rd answerer for question with Jetpack Compose tag. I love SubcomposeLayout, custom layout, animation, and gesture question especially.

https://stackoverflow.com/tags/android-jetpack-compose/topusers

https://www.linkedin.com/in/fatih-özcan-a2259b19b/

This is Jetpack Compose Tutorial i preapared that covers

Material Widgets, Layout, SubcomposeLayout, custom layouts, State, custom rememberable, recomposition, LaunchedEffect, side-effects, Gesture, Animation, Navigation, Canvas, UIs like whatsapp and others.

https://github.com/SmartToolFactory/Jetpack-Compose-Tutorials

And i have some libraries written with Jetpack Compose including

Image libraries with Jetpack Compose

https://github.com/SmartToolFactory/Compose-Image

Colorful Sliders With Jetpack Compose

https://github.com/SmartToolFactory/Compose-Colorful-Sliders

Collection of Cool Color Pickers with Jetpack Compose

https://github.com/SmartToolFactory/Compose-Color-Picker-Bundle

Color Detector with Jetpack Compose

https://github.com/SmartToolFactory/Compose-Color-Detector

Extended gestures for OnTouchEvent and extended transform gestures

https://github.com/SmartToolFactory/Compose-Extended-Gestures

Chat Layout that assigns position of message and status based on message lines and length and resizes children based on longest sibling like whatsapp

https://github.com/SmartToolFactory/Flexible-Chat-Box

You can contact me via [email protected]

compose-cropper's People

Contributors

manhnguyends3 avatar nimrodda avatar smarttoolfactory avatar

Stargazers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar  avatar

Watchers

 avatar  avatar  avatar  avatar  avatar  avatar  avatar

compose-cropper's Issues

Fixed crop overlay's aspect ratio in dynamic crop

Setting a crop overlay aspect ratio doesn't persist when resizing the crop overlay size.
I'd expected that setting an aspect ratio will enforce that the crop rectangle keeps the aspect ratio when resizing it.
Is this feature already implemented and I just missed it? 🤔
Some documentation would be nice

Background color behind image is hardcoded.

I am trying to set the background color using CropDefaults.style(backgroundColor = Color.Red but looks like it is not working as expected.
I would expect the background color to be a color behind the image and overlayColor color to be a color that is semi-transparent that allows seeing the picture outside the crop box.

Screenshot_20221110_110924

Crop with overlay ratio does not scale to full borders

Description

Current version of the library does not allow to zoom in lower scales than 1X, making usage of "overlay ratio" broken (especially, for static crop), because borders of crop cannot fill bounds of the picture

Preview

Current implementation

test1

Required behaviour

test2

java.lang.IllegalArgumentException: height must be > 0

Thanks for this, it's just what I need! :)

I copied your ImageCropDemoSimple Composable and I am getting this error:

java.lang.IllegalArgumentException: height must be > 0 at android.graphics.Bitmap.checkWidthHeight(Bitmap.java:443) at android.graphics.Bitmap.createBitmap(Bitmap.java:872) at android.graphics.Bitmap.createBitmap(Bitmap.java:834) at com.smarttoolfactory.cropper.image.ImageScopeKt.getScaledImageBitmap-pBklqvs(ImageScope.kt:117) at com.smarttoolfactory.cropper.ImageCropperKt$ImageCropper$1.invoke(ImageCropper.kt:67) at com.smarttoolfactory.cropper.ImageCropperKt$ImageCropper$1.invoke(ImageCropper.kt:63) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at com.smarttoolfactory.cropper.image.ImageWithConstraintsKt.ImageLayout-QnyEGeY(ImageWithConstraints.kt:189) at com.smarttoolfactory.cropper.image.ImageWithConstraintsKt.access$ImageLayout-QnyEGeY(ImageWithConstraints.kt:1) at com.smarttoolfactory.cropper.image.ImageWithConstraintsKt$ImageWithConstraints$1.invoke(ImageWithConstraints.kt:119) etc.

Any ideas?

Stable Version?

I am interested in using this library, what is the reason for this library not yet occupying a stable version?

Add offset for picture.

My question is similar to #4 but I need to solve it by adjusting the offset for a picture, not by removing the offset of an overlay. Is this possible?

It might look something like this:

Снимок экрана 2023-12-20 в 00 20 50

Expose cropping overlay and handles with callbacks

Hey, can you expose cropping overlay with handles so it can be used for any composable component? It could be a modifier or compose component which takes content over which to draw.

For example, I want to implement video cropper, and I would like to wrap your cropper UI over the existing video surface, and would like to get the state of the cropper; width, height, startX & startY so I can proceed with video processing.

Cropped image, not accurate.

I am using your libraries without any issues.

However, I noticed that the cropping is not happening exactly where I want it.

For instance, I'm using your library to crop a part of a text and recognize the text.

But it doesn't crop exactly where I want, and I have to adjust it further down; otherwise, the text doesn't fully appear in the crop.

Do you know how I can solve this?

My code:

@Composable
internal fun ScreenShotCropImage(
    isCrop: Boolean,
    modifier: Modifier = Modifier,
    imageBitmap: ImageBitmap? = rememberImageBitmap(),
    onCropImageResult: (ImageBitmap?) -> Unit,
) {
    val handleSize: Float = LocalDensity.current.run { 20.dp.toPx() }

    val cropProperties by remember {
        mutableStateOf(
            CropDefaults.properties(
                contentScale = ContentScale.Inside,
                cropOutlineProperty = CropOutlineProperty(
                    OutlineType.Rect,
                    RectCropShape(0, "Rect"),
                ),
                aspectRatio = aspectRatios[3].aspectRatio,
                handleSize = handleSize,
                overlayRatio = 0.2f,
                maxZoom = 4f,
            ),
        )
    }
    val cropStyle by remember {
        mutableStateOf(
            CropDefaults.style(drawGrid = false, strokeWidth = 2.dp),
        )
    }

    imageBitmap?.let { image ->
        ImageCropper(
            modifier = modifier
                .fillMaxWidth(),
            imageBitmap = image,
            contentDescription = null,
            cropStyle = cropStyle,
            cropProperties = cropProperties,
            crop = isCrop,
            onCropStart = {},
            onCropSuccess = onCropImageResult,
        )
    }
}

Wrong aspect ratio after scaling

Aspect ratio of cropped image is not exactly the one set in cropProperties.

Steps to reproduce in demo app:

  1. Select 9:16 aspect ratio from settings.
  2. Zoom image in or out. Don't change crop area
  3. Cropp
  4. Result image does not have 9/16 = 0.5625 aspect ratio, but something slightly different

Same behaviour is in static and dynamic mode
I did not successfully reproduce this for 1:1 aspect ratio.

Avoid empty spaces

Is there any way to avoid blank spaces?, that the drag limit is the image

Thanks!

photo_2022-10-13_11-04-20

Changing Background color

Thank you for the great lib, it seems that there is no way to change the background color from black as it is hard-coded and not passed by the modifier.

Lack of documentation

Great library with great potential, but the lack of any documentation makes using it very difficult. I also see that it is probably no longer supported by the author.

Crop area is not respected for the 9:16 ratio

Looks like there is a bug.
Steps to reproduce on Demo app:

  1. Select a 9:16 ratio
  2. Select an image from the gallery
  3. Press crop without taking any actions

Actual: The image is not cropped properly
Expected: The image is cropped according to the area selected

I notice that if I move the image a little bit it crops properly, the issue happens only if the user selected the image and takes no action to adjust the crop area

Video of the bug
https://github.com/SmartToolFactory/Compose-Cropper/assets/11620779/a4bf603f-a9e2-49e4-8afe-c7b1ce1d15f7

How to rotate image or selection area?

Hi! Firstly thank you for great lib! It's very useful
Could you help me to figure out how I can rotate image or selection area and get rotated cropped image?

Compose multiplatform

Hi
There isn't any image cropper library for compose multiplatform (jvm, android, ios, ...).
You created base of compose code and just need to change some code for compose multiplatform.
It will be very useful and i really need it.
Please work on it 🙏.

java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/compose/material/TouchTargetKt;

Edit: I found what is the problem. SmartToolFactory/Compose-Colorful-Sliders#12

I used to use the library without any problems. But right now I am getting an error like this. I tried downgrading and upgrading the Compose version but the result did not change. What could have caused it?

FATAL EXCEPTION: main Process: com.armutyus.cameraxproject, PID: 25488 java.lang.NoClassDefFoundError: Failed resolution of: Landroidx/compose/material/TouchTargetKt; at com.smarttoolfactory.slider.MinimumTouchKt$minimumTouchTargetSize$2.invoke(MinimumTouch.kt:27) at com.smarttoolfactory.slider.MinimumTouchKt$minimumTouchTargetSize$2.invoke(MinimumTouch.kt:19) at androidx.compose.ui.ComposedModifierKt$materialize$result$1.invoke(ComposedModifier.kt:265) at androidx.compose.ui.ComposedModifierKt$materialize$result$1.invoke(ComposedModifier.kt:260) at androidx.compose.ui.Modifier$Element.foldIn(Modifier.kt:115) at androidx.compose.ui.CombinedModifier.foldIn(Modifier.kt:301) at androidx.compose.ui.ComposedModifierKt.materialize(ComposedModifier.kt:260) at androidx.compose.ui.layout.SubcomposeLayoutKt.SubcomposeLayout(SubcomposeLayout.kt:110) at androidx.compose.ui.layout.SubcomposeLayoutKt.SubcomposeLayout(SubcomposeLayout.kt:75) at androidx.compose.foundation.layout.BoxWithConstraintsKt.BoxWithConstraints(BoxWithConstraints.kt:67) at com.smarttoolfactory.slider.ColorfulSliderKt.ColorfulSlider-rpZKZhI(ColorfulSlider.kt:168) at com.smarttoolfactory.slider.ColorfulSliderKt.ColorfulSlider-rpZKZhI(ColorfulSlider.kt:86) at com.armutyus.cameraxproject.ui.gallery.preview.editmedia.cropproperties.SelectionWidgetsKt.SliderSelection(SelectionWidgets.kt:103) at com.armutyus.cameraxproject.ui.gallery.preview.editmedia.cropproperties.CropPropertySelectionKt.CropPropertySelectionMenu(CropPropertySelection.kt:79) at com.armutyus.cameraxproject.ui.gallery.preview.editmedia.cropproperties.PropertySelectionSheetKt$PropertySelectionSheet$1.invoke(PropertySelectionSheet.kt:14) at com.armutyus.cameraxproject.ui.gallery.preview.editmedia.cropproperties.PropertySelectionSheetKt$PropertySelectionSheet$1.invoke(PropertySelectionSheet.kt:13) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at com.armutyus.cameraxproject.ui.gallery.preview.editmedia.cropproperties.BaseSheetKt$BaseSheet$1.invoke(BaseSheet.kt:43) at com.armutyus.cameraxproject.ui.gallery.preview.editmedia.cropproperties.BaseSheetKt$BaseSheet$1.invoke(BaseSheet.kt:17) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:132) at androidx.compose.material3.SurfaceKt$Surface$1.invoke(Surface.kt:114) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228) at androidx.compose.material3.SurfaceKt.Surface-T9BRK9s(Surface.kt:111) at com.armutyus.cameraxproject.ui.gallery.preview.editmedia.cropproperties.BaseSheetKt.BaseSheet(BaseSheet.kt:17) at com.armutyus.cameraxproject.ui.gallery.preview.editmedia.cropproperties.PropertySelectionSheetKt.PropertySelectionSheet(PropertySelectionSheet.kt:13) at com.armutyus.cameraxproject.ui.gallery.preview.editmedia.ImageCropModeKt$ImageCropMode$5.invoke(ImageCropMode.kt:144) at com.armutyus.cameraxproject.ui.gallery.preview.editmedia.ImageCropModeKt$ImageCropMode$5.invoke(ImageCropMode.kt:142) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1$6.invoke(ModalBottomSheet.kt:718) at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1$6.invoke(ModalBottomSheet.kt:541) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) 2023-03-24 14:45:34.907 25488-25488 AndroidRuntime com.armutyus.cameraxproject E at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.material.SurfaceKt$Surface$1.invoke(Surface.kt:137) at androidx.compose.material.SurfaceKt$Surface$1.invoke(Surface.kt:118) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.CompositionLocalKt.CompositionLocalProvider(CompositionLocal.kt:228) at androidx.compose.material.SurfaceKt.Surface-F-jzlyU(Surface.kt:115) at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1.invoke(ModalBottomSheet.kt:468) at androidx.compose.material.ModalBottomSheetKt$ModalBottomSheetLayout$1.invoke(ModalBottomSheet.kt:454) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:116) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.foundation.layout.BoxWithConstraintsKt$BoxWithConstraints$1$1$measurables$1.invoke(BoxWithConstraints.kt:69) at androidx.compose.foundation.layout.BoxWithConstraintsKt$BoxWithConstraints$1$1$measurables$1.invoke(BoxWithConstraints.kt:69) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$subcompose$3$1$1.invoke(SubcomposeLayout.kt:778) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$subcompose$3$1$1.invoke(SubcomposeLayout.kt:446) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:107) at androidx.compose.runtime.internal.ComposableLambdaImpl.invoke(ComposableLambda.jvm.kt:34) at androidx.compose.runtime.ActualJvm_jvmKt.invokeComposable(ActualJvm.jvm.kt:78) at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3352) at androidx.compose.runtime.ComposerImpl$doCompose$2$5.invoke(Composer.kt:3342) at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341) at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1) at androidx.compose.runtime.ComposerImpl.doCompose(Composer.kt:3342) at androidx.compose.runtime.ComposerImpl.composeContent$runtime_release(Composer.kt:3277) at androidx.compose.runtime.CompositionImpl.composeContent(Composition.kt:587) at androidx.compose.runtime.Recomposer.composeInitial$runtime_release(Recomposer.kt:966) at androidx.compose.runtime.ComposerImpl$CompositionContextImpl.composeInitial$runtime_release(Composer.kt:3952) at androidx.compose.runtime.ComposerImpl$CompositionContextImpl.composeInitial$runtime_release(Composer.kt:3952) at androidx.compose.runtime.ComposerImpl$CompositionContextImpl.composeInitial$runtime_release(Composer.kt:3952) at androidx.compose.runtime.CompositionImpl.setContent(Composition.kt:519) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcomposeInto(SubcomposeLayout.kt:466) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:439) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:430) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState.subcompose(SubcomposeLayout.kt:419) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$Scope.subcompose(SubcomposeLayout.kt:740) at androidx.compose.foundation.layout.BoxWithConstraintsKt$BoxWithConstraints$1$1.invoke-0kLqBqw(BoxWithConstraints.kt:69) at androidx.compose.foundation.layout.BoxWithConstraintsKt$BoxWithConstraints$1$1.invoke(BoxWithConstraints.kt:67) at androidx.compose.ui.layout.LayoutNodeSubcompositionsState$createMeasurePolicy$1.measure-3p2s80s(SubcomposeLayout.kt:598) 2023-03-24 14:45:34.908 25488-25488 AndroidRuntime com.armutyus.cameraxproject E at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:103) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1090) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1086) at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2200) at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:234) at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:230) at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341) at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1) at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230) at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120) at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release(OwnerSnapshotObserver.kt:107) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1086) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:36) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:342) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.measure-BRTryo0(LayoutNodeLayoutDelegate.kt:321) at androidx.compose.foundation.layout.BoxKt$boxMeasurePolicy$1.measure-3p2s80s(Box.kt:115) at androidx.compose.ui.node.InnerNodeCoordinator.measure-BRTryo0(InnerNodeCoordinator.kt:103) at androidx.compose.ui.graphics.SimpleGraphicsLayerModifier.measure-3p2s80s(GraphicsLayerModifier.kt:635) at androidx.compose.ui.node.LayoutModifierNodeCoordinator.measure-BRTryo0(LayoutModifierNodeCoordinator.kt:155) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1090) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$performMeasure$2.invoke(LayoutNodeLayoutDelegate.kt:1086) at androidx.compose.runtime.snapshots.Snapshot$Companion.observe(Snapshot.kt:2200) at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:234) at androidx.compose.runtime.snapshots.SnapshotStateObserver$observeReads$1$1.invoke(SnapshotStateObserver.kt:230) at androidx.compose.runtime.SnapshotStateKt__DerivedStateKt.observeDerivedStateRecalculations(DerivedState.kt:341) at androidx.compose.runtime.SnapshotStateKt.observeDerivedStateRecalculations(Unknown Source:1) at androidx.compose.runtime.snapshots.SnapshotStateObserver.observeReads(SnapshotStateObserver.kt:230) at androidx.compose.ui.node.OwnerSnapshotObserver.observeReads$ui_release(OwnerSnapshotObserver.kt:120) at androidx.compose.ui.node.OwnerSnapshotObserver.observeMeasureSnapshotReads$ui_release(OwnerSnapshotObserver.kt:107) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:1086) at androidx.compose.ui.node.LayoutNodeLayoutDelegate.access$performMeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:36) at androidx.compose.ui.node.LayoutNodeLayoutDelegate$MeasurePassDelegate.remeasure-BRTryo0(LayoutNodeLayoutDelegate.kt:342) at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release(LayoutNode.kt:1173) at androidx.compose.ui.node.LayoutNode.remeasure-_Sx5XlM$ui_release$default(LayoutNode.kt:1164) at androidx.compose.ui.node.MeasureAndLayoutDelegate.doRemeasure-sdFAvZA(MeasureAndLayoutDelegate.kt:309) at androidx.compose.ui.node.MeasureAndLayoutDelegate.remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:434) at androidx.compose.ui.node.MeasureAndLayoutDelegate.access$remeasureAndRelayoutIfNeeded(MeasureAndLayoutDelegate.kt:39) 2023-03-24 14:45:34.915 25488-25488 AndroidRuntime com.armutyus.cameraxproject E at androidx.compose.ui.node.MeasureAndLayoutDelegate.measureAndLayout(MeasureAndLayoutDelegate.kt:330) at androidx.compose.ui.platform.AndroidComposeView.measureAndLayout(AndroidComposeView.android.kt:778) at androidx.compose.ui.node.Owner.measureAndLayout$default(Owner.kt:216) at androidx.compose.ui.platform.AndroidComposeView.dispatchDraw(AndroidComposeView.android.kt:1008) at android.view.View.draw(View.java:22508) at android.view.View.updateDisplayListIfDirty(View.java:21367) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4535) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4508) at android.view.View.updateDisplayListIfDirty(View.java:21325) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4535) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4508) at android.view.View.updateDisplayListIfDirty(View.java:21325) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4535) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4508) at android.view.View.updateDisplayListIfDirty(View.java:21325) at android.view.ViewGroup.recreateChildDisplayList(ViewGroup.java:4535) at android.view.ViewGroup.dispatchGetDisplayList(ViewGroup.java:4508) at android.view.View.updateDisplayListIfDirty(View.java:21325) at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:559) at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:567) at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:651) at android.view.ViewRootImpl.draw(ViewRootImpl.java:4274) at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3979) at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:3240) at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:2066) at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:8496) at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1076) at android.view.Choreographer.doCallbacks(Choreographer.java:897) at android.view.Choreographer.doFrame(Choreographer.java:826) at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1061) at android.os.Handler.handleCallback(Handler.java:938) at android.os.Handler.dispatchMessage(Handler.java:99) at android.os.Looper.loop(Looper.java:236) at android.app.ActivityThread.main(ActivityThread.java:8061) at java.lang.reflect.Method.invoke(Native Method) at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:656) at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:967) Caused by: java.lang.ClassNotFoundException: Didn't find class "androidx.compose.material.TouchTargetKt" on path: DexPathList[[zip file "/data/app/~~nYn-U1LtzSuDMkLL47qYfQ==/com.armutyus.cameraxproject-sdiOo9qvherHnO-50oo1yw==/base.apk"],nativeLibraryDirectories=[/data/app/~~nYn-U1LtzSuDMkLL47qYfQ==/com.armutyus.cameraxproject-sdiOo9qvherHnO-50oo1yw==/lib/arm64, /data/app/~~nYn-U1LtzSuDMkLL47qYfQ==/com.armutyus.cameraxproject-sdiOo9qvherHnO-50oo1yw==/base.apk!/lib/arm64-v8a, /system/lib64, /system/system_ext/lib64]] at dalvik.system.BaseDexClassLoader.findClass(BaseDexClassLoader.java:207) at java.lang.ClassLoader.loadClass(ClassLoader.java:379) at java.lang.ClassLoader.loadClass(ClassLoader.java:312) ... 151 more

it's just a suggestion

@Composable
fun ImageCropper(
	modifier: Modifier = Modifier,
	imageBitmap: ImageBitmap,
	contentDescription: String?,
	cropStyle: CropStyle = CropDefaults.style(),
	cropProperties: CropProperties,
	filterQuality: FilterQuality = DrawScope.DefaultFilterQuality,
	crop: Boolean = false,
	backgroundColor: Color = Color.Black,
	onCropStart: () -> Unit,
	onCropSuccess: (ImageBitmap) -> Unit
) {

..

		val transparentColor by animateColorAsState(
			animationSpec = tween(300, easing = LinearEasing),
			targetValue = if (isTouched.value) backgroundColor.copy(alpha = .5f) else backgroundColor.copy(alpha = .7f)
		)

..

		ImageCropper(
			modifier = imageModifier,
			visible = visible,
			imageBitmap = imageBitmap,
			containerWidth = containerWidth,
			containerHeight = containerHeight,
			imageWidthPx = imageWidthPx,
			imageHeightPx = imageHeightPx,
			handleSize = cropProperties.handleSize,
			overlayRect = cropState.overlayRect,
			cropType = cropType,
			cropOutline = cropOutline,
			cropStyle = cropStyle,
			transparentColor = transparentColor,
			backgroundColor = backgroundColor
		)

..

}

Thank you :)

Fatal Exception: java.lang.RuntimeException Canvas: trying to draw too large(192000000bytes) bitmap

I am using Compose-Cropper in one of my apps. I am receiving the below error for many users. The Bitmap size mentioned is random but usually large.

Fatal Exception: java.lang.RuntimeException
Canvas: trying to draw too large(201326592bytes) bitmap.
android.graphics.RecordingCanvas.throwIfCannotDraw (RecordingCanvas.java:287)

androidx.compose.ui.graphics.drawscope.DrawScope.drawImage-AZ2fEMs$default (DrawScope.kt:510)
com.smarttoolfactory.cropper.draw.ImageDrawCanvasKt$ImageDrawCanvas$1.invoke (ImageDrawCanvas.kt:26)
com.smarttoolfactory.cropper.draw.ImageDrawCanvasKt$ImageDrawCanvas$1.invoke (ImageDrawCanvas.kt:21)
androidx.compose.ui.draw.DrawBackgroundModifier.draw (DrawModifier.kt:116)

com.android.internal.os.ZygoteInit.main (ZygoteInit.java:1049)

Is there any workaround that can be implemented to prevent this exception?

Different crop shape from the overlay cutout

Currently there isn't a way to have different crop shape than the overlay cutout.
The use case would be when the overlay cutout represents the way the data is presented in the application rather than the way we actually want to crop the image.

I have read the code a bit and seems like a simple fix would be to provide a way to override the crop behaviour i.e a lambda in the api that receives the actually crop args and expects an ImageBitmap with default value equal to the current cropAgent.crop call.

Alternatively we can change the onCropStart to have this functionality.

What do you think?

If you approve the general approach I can do a PR and there we could iron out the details.

How Can I Add a compose to the Crop Position?

Hi! I just started exploring your library, and I find it great with many possible customizations!

But I have a question...

I would like to get the crop position and add a tooltip or tip on top. Is there a way for me to implement this?

Add drag sides of crop box

Now it is only possible to drag corners, but it will be really helpful to add dragging for the sides of crop box too, like a 4 additional drag handles, which will be positioned at each edr of crop box

No drag cropping does not work

When I don't drag the crop, for example, I select 1:1 square and then click crop directly, the resulting image is the original rectangle without the crop. If I move the image or crop box slightly, it works fine. demo can also reproduce this problem.

API request, animated visibility enter/exit

Issue:

When rendering full screen ImageCropper() over already full screen image, there is transition:

Current Desired
transition-before.mp4
transition-after.mp4

Request/suggestions:

  • Let user define enter/exit animations (Will pollute ImageCropper params, it might be okay with default param?)
  • Remove AnimatedVisibility and let user Animate the transition from parent composable (not sure how this would play out)

Compose multiplatform

Hi
Please create this library to compose multiplatform.
there isn't any library to crop image for compose multiplatform.

Recommend Projects

  • React photo React

    A declarative, efficient, and flexible JavaScript library for building user interfaces.

  • Vue.js photo Vue.js

    🖖 Vue.js is a progressive, incrementally-adoptable JavaScript framework for building UI on the web.

  • Typescript photo Typescript

    TypeScript is a superset of JavaScript that compiles to clean JavaScript output.

  • TensorFlow photo TensorFlow

    An Open Source Machine Learning Framework for Everyone

  • Django photo Django

    The Web framework for perfectionists with deadlines.

  • D3 photo D3

    Bring data to life with SVG, Canvas and HTML. 📊📈🎉

Recommend Topics

  • javascript

    JavaScript (JS) is a lightweight interpreted programming language with first-class functions.

  • web

    Some thing interesting about web. New door for the world.

  • server

    A server is a program made to process requests and deliver data to clients.

  • Machine learning

    Machine learning is a way of modeling and interpreting data that allows a piece of software to respond intelligently.

  • Game

    Some thing interesting about game, make everyone happy.

Recommend Org

  • Facebook photo Facebook

    We are working to build community through open source technology. NB: members must have two-factor auth.

  • Microsoft photo Microsoft

    Open source projects and samples from Microsoft.

  • Google photo Google

    Google ❤️ Open Source for everyone.

  • D3 photo D3

    Data-Driven Documents codes.