OutOfMemory error while trying to rotate image inside image

Im trying to rotate the image inside the imageView, as well as flip the bitmap with the same image.

(I need this bitmap because Im sending the image to the server later)

The code:

image.setOnClickListener(new OnClickListener() { public void onClick(View view) { mPhoto=rotate(mPhoto,90); image.setImageBitmap(mPhoto); } }); 

rotate ():

 public static Bitmap rotate(Bitmap src, float degree) { // create new matrix Matrix matrix = new Matrix(); // setup rotation degree matrix.postRotate(degree); // return new bitmap rotated using matrix return Bitmap.createBitmap(src, 0, 0, src.getWidth(), src.getHeight(), matrix, true); } 

Logcat:

 08-29 23:14:34.964: W/dalvikvm(20087): threadid=1: thread exiting with uncaught exception (group=0x41505930) 08-29 23:14:34.968: E/AndroidRuntime(20087): FATAL EXCEPTION: main 08-29 23:14:34.968: E/AndroidRuntime(20087): java.lang.OutOfMemoryError 08-29 23:14:34.968: E/AndroidRuntime(20087): at android.graphics.Bitmap.nativeCreate(Native Method) 08-29 23:14:34.968: E/AndroidRuntime(20087): at android.graphics.Bitmap.createBitmap(Bitmap.java:689) 08-29 23:14:34.968: E/AndroidRuntime(20087): at android.graphics.Bitmap.createBitmap(Bitmap.java:666) 08-29 23:14:34.968: E/AndroidRuntime(20087): at android.graphics.Bitmap.createBitmap(Bitmap.java:599) 08-29 23:14:34.968: E/AndroidRuntime(20087): at com.example.free.Add.rotate(Add.java:356) 08-29 23:14:34.968: E/AndroidRuntime(20087): at com.example.free.Add$5.onClick(Add.java:137) 08-29 23:14:34.968: E/AndroidRuntime(20087): at android.view.View.performClick(View.java:4211) 08-29 23:14:34.968: E/AndroidRuntime(20087): at android.view.View$PerformClick.run(View.java:17362) 08-29 23:14:34.968: E/AndroidRuntime(20087): at android.os.Handler.handleCallback(Handler.java:725) 08-29 23:14:34.968: E/AndroidRuntime(20087): at android.os.Handler.dispatchMessage(Handler.java:92) 08-29 23:14:34.968: E/AndroidRuntime(20087): at android.os.Looper.loop(Looper.java:137) 08-29 23:14:34.968: E/AndroidRuntime(20087): at android.app.ActivityThread.main(ActivityThread.java:5227) 08-29 23:14:34.968: E/AndroidRuntime(20087): at java.lang.reflect.Method.invokeNative(Native Method) 08-29 23:14:34.968: E/AndroidRuntime(20087): at java.lang.reflect.Method.invoke(Method.java:511) 08-29 23:14:34.968: E/AndroidRuntime(20087): at com.android.internal.os.ZygoteInit$MethodAndArgsCaller.run(ZygoteInit.java:795) 08-29 23:14:34.968: E/AndroidRuntime(20087): at com.android.internal.os.ZygoteInit.main(ZygoteInit.java:562) 08-29 23:14:34.968: E/AndroidRuntime(20087): at dalvik.system.NativeStart.main(Native Method) 

I hope you help me.

Ty!

+4
source share
5 answers

Based on your comment: 2560X1920. Its big, but I have to find a way to fit it in.. @gunar - I have to show this image to the user before sending it to the server 2560X1920. Its big, but I have to find a way to fit it in.. @gunar - I have to show this image to the user before sending it to the server .

To display an image for the user, you first need to resize it. Follow the famous developer article on how to efficiently download and display bitmaps.

But in this case, you will need to take into account the rotation when calculating the parameters for the width and height (I think you are using Exif info).

Sending a large image to the server is more difficult. I saw this post on how to rotate large images, but I did not have time to try this. The idea is to rotate the raster image matrix into another target raster map.

However, I would suggest turning the image on the server side or if you cannot make changes on the server side because it does not belong to you, create your own proxy server, send your image to this instance, rotate it there and from there send the rotated image to the original server (by forwarding any data that the Android client usually sends).

+1
source

Try this when you decode a file

 File imgFile = new File("yourPath"); BitmapFactory.Options options = new BitmapFactory.Options(); options.inSampleSize = 10; Bitmap myBitmap = BitmapFactory.decodeFile(imgFile.getAbsolutePath(), options); 

then you call

 rotate(myBitmap,90); 

From BitmapFactory.Options docs:

public int inSampleSize

Added to API level 1 If set to> 1, it requests a decoder to subsample the original image, returning a smaller image to save memory. The sample size is the number of pixels in any dimension that corresponds to one pixel in the decoded bitmap. For example, inSampleSize == 4 returns an image equal to 1/4 of the width / height of the original, and 1/16 the number of pixels. Any value <= 1 is treated in the same way as 1. Note: the decoder uses a final value based on powers of 2, any other value will be rounded to the nearest power of 2.

Hope this helps

0
source

Please see this related issue also posted in SO

It seems that some calls to recycle() must be performed on the rotated bitmap, so the memory allocated on it is freed, suggesting that the old non-rotated version of the bitmap will not be used.

Also check out the Bitmap Class Documentation

0
source

Instead of highlighting a new 2560 x 1920 bitmap each time you rotate, why not link to android.graphics.Matrix in the same volume as ImageView and use image.setScaleType(ScaleType.MATRIX); image.setImageMatrix(matrix); image.setScaleType(ScaleType.MATRIX); image.setImageMatrix(matrix); ?

Your rotation method might look like this:

 if (mMatrix == null) { mMatrix = new Matrix(); } mMatrix.postRotate(degrees); mImageView.setImageMatrix(mMatrix); 
0
source

Before starting the optimization, I would make sure that you ran out of memory on real target devices, and not just in the emulator. If it works fine on the device itself, check your piece in your virtual machine script. You can also request additional memory on devices through the manifest by setting android: largeHeap = "true" in the tag. If after following these steps you still encounter device restrictions, yup, you need to optimize.

Perhaps image manipulation is simply too taxable for such a large bitmap on some devices. I noted that you plan to send this to the server. Can I assume that you want the image to be rotated correctly for display on the server side? If so, you can always manipulate them, for example with PIL, if you use Python. Just a thought.

Good luck.

0
source

Source: https://habr.com/ru/post/1499694/


All Articles