Xamarin.Plugin.ImageEdit icon indicating copy to clipboard operation
Xamarin.Plugin.ImageEdit copied to clipboard

Crash after some calls to CreateImageAsync

Open Nico04 opened this issue 5 years ago • 4 comments

On some Android devices, my app crashes after 2 or 3 times doing the same operation on different images.

Here is the callstack :

Java.Lang.OutOfMemoryError: Failed to allocate a 57802764 byte allocation with 8388608 free bytes and 39MB until OOM
  at Java.Interop.JniEnvironment+StaticMethods.CallStaticObjectMethod (Java.Interop.JniObjectReference type, Java.Interop.JniMethodInfo method, Java.Interop.JniArgumentValue* args) [0x00069] in <8acc8089c2ed40d08469fbaa6710a44c>:0 
  at Java.Interop.JniPeerMembers+JniStaticMethods.InvokeObjectMethod (System.String encodedMember, Java.Interop.JniArgumentValue* parameters) [0x00018] in <8acc8089c2ed40d08469fbaa6710a44c>:0 
  at Android.Graphics.BitmapFactory.DecodeByteArray (System.Byte[] data, System.Int32 offset, System.Int32 length) [0x00052] in <957bbfdfda4341e2939c881206c1140a>:0 
  at Plugin.ImageEdit.EditableImage..ctor (System.Byte[] bin) [0x00006] in <cbc390f592694505b141808a24ab2d19>:0 
  at Plugin.ImageEdit.ImageEdit.CreateImage (System.Byte[] imageArray) [0x00000] in <cbc390f592694505b141808a24ab2d19>:0 
  at Plugin.ImageEdit.ImageEdit+<>c__DisplayClass1_0.<CreateImageAsync>b__0 () [0x00000] in <cbc390f592694505b141808a24ab2d19>:0 
  at System.Threading.Tasks.Task`1[TResult].InnerInvoke () [0x0000f] in <d4a23bbd2f544c30a48c44dd622ce09f>:0 
  at System.Threading.Tasks.Task.Execute () [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0 
--- End of stack trace from previous location where exception was thrown ---
  at Plugin.ImageEdit.ImageEdit+<CreateImageAsync>d__1.MoveNext () [0x00087] in <cbc390f592694505b141808a24ab2d19>:0 
--- End of stack trace from previous location where exception was thrown ---
  at MeilleureVisite.SaveServices+<SaveThumbnailToFileFromFullSizePicture>d__15.MoveNext () [0x00039] in C:\Users\Nicolas\source\repos\MeilleureVisite\MeilleureVisite\MeilleureVisite\Services\SaveServices.cs:120 
--- End of stack trace from previous location where exception was thrown ---
  at MeilleureVisite.CaptureViewModel+<ValidateCapture>d__140.MoveNext () [0x00039] in C:\Users\Nicolas\source\repos\MeilleureVisite\MeilleureVisite\MeilleureVisite\ViewModels\CaptureViewModel.cs:656 
--- End of stack trace from previous location where exception was thrown ---
  at System.Runtime.CompilerServices.AsyncMethodBuilderCore+<>c.<ThrowAsync>b__6_0 (System.Object state) [0x00000] in <d4a23bbd2f544c30a48c44dd622ce09f>:0 
  at Android.App.SyncContext+<>c__DisplayClass2_0.<Post>b__0 () [0x00000] in <957bbfdfda4341e2939c881206c1140a>:0 
  at Java.Lang.Thread+RunnableImplementor.Run () [0x00008] in <957bbfdfda4341e2939c881206c1140a>:0 
  at Java.Lang.IRunnableInvoker.n_Run (System.IntPtr jnienv, System.IntPtr native__this) [0x00009] in <957bbfdfda4341e2939c881206c1140a>:0 
  at (wrapper dynamic-method) System.Object.43(intptr,intptr)
  --- End of managed Java.Lang.OutOfMemoryError stack trace ---
java.lang.OutOfMemoryError: Failed to allocate a 57802764 byte allocation with 8388608 free bytes and 39MB until OOM
	at dalvik.system.VMRuntime.newNonMovableArray(Native Method)
	at android.graphics.BitmapFactory.nativeDecodeByteArray(Native Method)
	at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:522)
	at android.graphics.BitmapFactory.decodeByteArray(BitmapFactory.java:545)

I've checked my code dispose the image :

using (IEditableImage image = await CrossImageEdit.Current.CreateImageAsync(fullSizePicture).NoSync()) {
...
}

Here are the devices on were the issue is reproducible :

  • Samsung A3 2015 (SM-A300FU) - Android 6.0.1 - 1.5Go RAM
  • Samsung S4 Mini - Android 6.0.1 - 1.5Go RAM
  • Samsung J3 2016 (SM-J320FN) - Android 5.1.1 - 1.5Go RAM
  • Samsung A5 2017 (SM-A520F) - Android 8.0.0 - 3Go RAM

I've tried android:largeHeap="true" but it's the same result...

Do you have any idea how to solve that please ?

Nico04 avatar Feb 21 '19 10:02 Nico04

After some in-depth digging, I found a fix. The key is to use the BitmapFactory.Options.InSampleSize to load a down-scaled version of the bitmap in memory. I had to modify your library to do so, if you want some code sample just ask ;)

Nico04 avatar Feb 21 '19 13:02 Nico04

@Nico04 Thank you for your report and survey. And I'm sorry for the delay in my reply.

Could you tell me your fix code? Alternatively, I was wondering if you could send pull request about fix code.

Thanks.

muak avatar Apr 10 '19 01:04 muak

Hi, Please find my code fix sample : https://www.myqnapcloud.com/smartshare/61h1f5k4np2m2651w58vaxcy_6nh1tuk

Unfortunately it's too long for me to make a proper pull request, but you should find the code fix easy to understand. Most of the work is on the Android/ImageEdit.cs file.

Let me know if you need more info. :)

Nico04 avatar Apr 21 '19 18:04 Nico04

@Nico04 Thank you for your fix sample.

I will update this library with your sample before long. Thanks.

muak avatar Apr 24 '19 11:04 muak