React-native-image-crop-picker: Android app crashes with cropping enabled on large images

Created on 13 May 2020  路  6Comments  路  Source: ivpusic/react-native-image-crop-picker

Version

Tell us which versions you are using:

  • react-native-image-crop-picker v0.30.0
  • react-native v0.62.1

Platform

Tell us to which platform this issue is related

  • Android

Expected behaviour

Pick a large image in the Android gallery (>5MB), then show the cropping interface.

Actual behaviour

The user selects the large image file, then the app crashes before the cropping interface appears with the stack below.

With the flag android:hardwareAccelerated="false" it doesn't happen, but the app becomes so slow it is unusable.

Steps to reproduce

  1. Asks the user to pick an image in its gallery, with cropping enabled

  2. The user chooses a large file > 5MB

  3. The app crashes

Attachments

java.lang.RuntimeException: Canvas: trying to draw too large(192000000bytes) bitmap.
    at android.view.DisplayListCanvas.throwIfCannotDraw(DisplayListCanvas.java:229)
    at android.view.RecordingCanvas.drawBitmap(RecordingCanvas.java:98)
    at com.yalantis.ucrop.util.FastBitmapDrawable.draw(FastBitmapDrawable.java:41)
    at android.widget.ImageView.onDraw(ImageView.java:1360)
    at android.view.View.draw(View.java:20234)
    at android.view.View.updateDisplayListIfDirty(View.java:19109)
    at android.view.View.draw(View.java:19962)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
    at android.view.View.updateDisplayListIfDirty(View.java:19100)
    at android.view.View.draw(View.java:19962)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
    at android.view.View.draw(View.java:20237)
    at android.view.View.updateDisplayListIfDirty(View.java:19109)
    at android.view.View.draw(View.java:19962)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
    at android.view.View.updateDisplayListIfDirty(View.java:19100)
    at android.view.View.draw(View.java:19962)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
    at android.view.View.updateDisplayListIfDirty(View.java:19100)
    at android.view.View.draw(View.java:19962)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
    at android.view.View.updateDisplayListIfDirty(View.java:19100)
    at android.view.View.draw(View.java:19962)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
    at android.view.View.updateDisplayListIfDirty(View.java:19100)
    at android.view.View.draw(View.java:19962)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
    at android.view.View.updateDisplayListIfDirty(View.java:19100)
    at android.view.View.draw(View.java:19962)
    at android.view.ViewGroup.drawChild(ViewGroup.java:4337)
    at android.view.ViewGroup.dispatchDraw(ViewGroup.java:4114)
    at android.view.View.draw(View.java:20237)
    at com.android.internal.policy.DecorView.draw(DecorView.java:784)
    at android.view.View.updateDisplayListIfDirty(View.java:19109)
    at android.view.ThreadedRenderer.updateViewTreeDisplayList(ThreadedRenderer.java:686)
    at android.view.ThreadedRenderer.updateRootDisplayList(ThreadedRenderer.java:692)
    at android.view.ThreadedRenderer.draw(ThreadedRenderer.java:801)
    at android.view.ViewRootImpl.draw(ViewRootImpl.java:3402)
    at android.view.ViewRootImpl.performDraw(ViewRootImpl.java:3199)
    at android.view.ViewRootImpl.performTraversals(ViewRootImpl.java:2558)
    at android.view.ViewRootImpl.doTraversal(ViewRootImpl.java:1535)
    at android.view.ViewRootImpl$TraversalRunnable.run(ViewRootImpl.java:7405)
    at android.view.Choreographer$CallbackRecord.run(Choreographer.java:1044)
    at android.view.Choreographer.doCallbacks(Choreographer.java:839)
    at android.view.Choreographer.doFrame(Choreographer.java:774)
    at android.view.Choreographer$FrameDisplayEventReceiver.run(Choreographer.java:1030)
    at android.os.Handler.handleCallback(Handler.java:873)
    at android.os.Handler.dispatchMessage(Handler.java:99)
    at android.os.Looper.loop(Looper.java:201)
    at android.app.ActivityThread.main(ActivityThread.java:6864)
    at java.lang.reflect.Method.invoke(Native Method)
    at com.android.internal.os.RuntimeInit$MethodAndArgsCaller.run(RuntimeInit.java:547)
    at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:873)

Most helpful comment

I resolve this problem when i use ImageResizer.createResizedImage to compress image. then ImagePicker.openCropper to cropper. 10M image no crashes at mi 10.

import ImageResizer from 'react-native-image-resizer';
import ImagePicker from 'react-native-image-crop-picker';
ImagePicker.openPicker({
    cropping: false,
    cropperToolbarColor: Global.primaryColor,
  }).then(image => {
    console.log(image);
    let divider = 1;
    if (image.size > 300000) {
      divider = image.size / 300000;
    }
    ImageResizer.createResizedImage(
      image.path,
      image.width / divider,
      image.height / divider,
      'JPEG',
      100,
      0,
      null,
    ).then(resp => {
      ImagePicker.openCropper({
        path: resp.uri,
      }).then(image => {

All 6 comments

Same problem here!

Same problem here! Can you check picture size or callback a function to custumer before crop a image. File change event is necessary.We can compress images to a reasonable range and instead of crash.

Same problem for me too. App getting crash on selecting morethan 5mb to crop

I have made some researches, but I'm still unable to fix the crash:

  • The bug can be fixed by moving the image to the drawable folder, but I don't know if it's possible as the drawable folder seems to be only for static images
  • An other solution could be reducing image size before the image is cropped
  • The error is thrown from the DisplayListCanvas from Android SDK used in the uCrop library (https://github.com/Yalantis/uCrop)
int bitmapSize = bitmap.getByteCount();
if (bitmapSize > MAX_BITMAP_SIZE) {
     throw new RuntimeException(
         "Canvas: trying to draw too large(" + bitmapSize + "bytes) bitmap.");
 }

If someone with good skills in Android could take a look it could be awesome. It's a real problem as all recent Android devices take high-res pictures that almost always crash.

I resolve this problem when i use ImageResizer.createResizedImage to compress image. then ImagePicker.openCropper to cropper. 10M image no crashes at mi 10.

import ImageResizer from 'react-native-image-resizer';
import ImagePicker from 'react-native-image-crop-picker';
ImagePicker.openPicker({
    cropping: false,
    cropperToolbarColor: Global.primaryColor,
  }).then(image => {
    console.log(image);
    let divider = 1;
    if (image.size > 300000) {
      divider = image.size / 300000;
    }
    ImageResizer.createResizedImage(
      image.path,
      image.width / divider,
      image.height / divider,
      'JPEG',
      100,
      0,
      null,
    ).then(resp => {
      ImagePicker.openCropper({
        path: resp.uri,
      }).then(image => {

@huaSoftware
Thanks very much, working great for me !

Was this page helpful?
0 / 5 - 0 ratings

Related issues

Martian2Lee picture Martian2Lee  路  3Comments

xuchao321 picture xuchao321  路  3Comments

DISKONEKTeD picture DISKONEKTeD  路  3Comments

JodiWarren picture JodiWarren  路  3Comments

pavsidhu picture pavsidhu  路  3Comments