I have a Scrollview that contains 4 big size images 750x1023, 750x2265, 750x1898, and 750x1112
I load image with Picasso
Picasso.with(getContext()).load(resIds[i]).fit().centerCrop().into(mainImageview.get(i));
But it brings to OutOfMemory error.
It makes to problem:
not all images load
app closing
Its important not to make image smaller - it can make UI uncorrect.
What the way to solve this problem? id need, to post code of program - just say what piece.
Thanks!
After all manipulation, problem is still unsolved.. If i scale images with BitmapFactory, it gives "Bitmap too large to bu uploaded into a texture", what ever size i write. If a scale with picasso, it crops my image What ever i do, app memmory enought for two, three switching pages... I'm exhausted because of this problem ...Help
The issue I believe is with gl max size which is something like 2048x2048 and the error will be cannot apply texture or something to that effect Picasso has a lot of ways to scale images but if you must use the full size image then its possible to cut the image into 4 or more pieces and assemble it like Google maps check this "Bitmap too large to be uploaded into a texture"
Related
I'm taking whole screenshot of a WebView and display the bitmap on an ImageView. The bitmap can be 7 screen height. (E.g. 1440x14000 px)
I'm frequently face with
OutOfMemoryError.
I've seen this
This says that load a scaled down version into memory but I don't want to lose image quality. There are the same approaches on the web.
Is there any way to handle OutOfMemoryError without loading scaled down version?
The bitmap can be 7 screen height. (E.g. 1440x14000 px)
Note that this means that the user cannot see the whole image at once at full resolution.
I'm frequently face with OutOfMemoryError
On most devices, you will have a very difficult time loading an image that large, as you cannot get a single contiguous memory block that big.
This says that load a scaled down version into memory but I don't want to lose image quality
To some extent, you do not have much of a choice. If you want the user to see the full extent of the picture at once, the image has to be scaled to fit the screen.
Is there any way to handle OutOfMemoryError without loading scaled down version?
There are ImageView replacements that offer pan and zoom. Some of those, such as this one, handle loading in pieces of the image at a time, with whatever scaling is necessary for the current zoom level, to make it more likely that you will be able to show the user the entire image.
It is not a solution, of course, but I'm also not familiar with your exact needs, so maybe this may help you a little - you can try to play with bitmap options during decoding. Try to use Bitmap.Config.inPreferredConfig as RGB_565 - this will reduce size of your bitmap twice comparing to default ARGB_8888. But, of course, if you use complex images in your web page this may reduce their quality.
In my app I'm generating a bunch of Bitmaps at runtime to show in a GridView. The generated Bitmaps consist only of rectangular shapes and about five different colors.
If I make them big, they get scaled down nicely, but I get OutOfMemoryExceptions. But when I make them small, they're not scaled up to fit the column width. I think ImageView can't help me, because it doesn't know the final column with. Setting stretchMode to columnWidth in the GridView didn't help.
Setting adjustViewBounds to true on the ImageView helped with large Bitmaps, but it doesn't help for upscaling.
Is it somehow possible to scale the ImageView with the underlying Bitmap to the maximum column width of the GridView? This would be my preferred solution.
If not, can I determine the columnWidth of the GridView in advance to just generate the bitmap accordingly? (I don't like this solution that much, because I suspect that on devices with large screens I might run into OutOfMemoryExceptions again.)
You have two choices.
METHOD 1:
Optimize your images by using any online image compression sites . For example https://tinypng.com .TinyPNG uses smart lossy compression techniques to reduce the file size of your PNG files. By selectively decreasing the number of colors in the image, fewer bytes are required to store the data. The effect is nearly invisible but it makes a very large difference in file size!
METHOD 2:
Load your images using third party libraries like Universal Image Loader, Glide .. these libraries aims to provide a powerful, flexible and highly customizable instrument for image loading, caching and displaying. It provides a lot of configuration options and good control over the image loading and caching process.
Since you generate the bitmaps in your app, you can use libraries like Picasso to display them. Picasso will handle the memory on your behalf and you need not worry about OutOfMemory Exceptions.
So, I have been using this amazing library Glide for showing native images in my gallery app. I am using ViewPager with FragmentStatePagerAdapter to show full size images. The pager's off screen limit is 1 (default to save memory). I am using this code to load images into ViewPager in my fragment:
Glide.with(getActivity())
.loadFromMediaStore(uri)
.asBitmap()
.signature(new MediaStoreSignature(mimeType, dateModified,
.into(mImageView);
Now, I am facing some issues here like:
Images take quite some amount of time to load (if not cached). So, while user is scrolling through the viewpager blank screen is shown while image is loading which is what I want to avoid. Is there any way I can do this? Maybe by precaching images?
Sometimes, while scrolling through large size images (mainly Camera photos) OOM Exception is thrown and user is left with blank screen as no image is loaded. This also happens when I am shifting from potrait to landscape mode. So, I tried to use methods like atMost() -- which degrade the quality of image further as images are already loaded in RGB_565 and approximate() which is also causing OOM. How can I achieve maximum image quality without getting OOM exceptions?
For the second issue, I was thinking to load lesser quality images for the off screen items and then enhance quality when they come on-screen. Is it possible?
I have also tried to use ARGB_8888 but the result was same: OOM exception.
TL;DR
Make sure the ImageView has match_parent or fixed dp as dimensions
wrap_content makes Glide load full resolution Bitmaps.
.placeholder() shows an image instead of empty space while loading large bitmap
.thumbnail(float) loads a downsampled version fast while the bigger image is loading in the background
Also look around the Glide issues, maybe you find something helpful.
Details
I would be curious what the xml is for the ImageView, because my guess is it's wrap_content which results in loading images at full resolution into Bitmaps (using a lot of memory). If that's the case I would suggest using match_parent or fixed dp to lower the resolution. Note: you won't use detail, because currently the image is downsampled at render time anyway, just pulling that forward to decoding phase.
You also have to make sure that your app doesn't have constraints for memory usage. Can you load 3 (off screen limit = 1 means 1+current+1 pages) camera photos into Bitmaps without Glide? Again, assuming this is full resolution, it should be possible to store 3 screen size amount of bytes in memory with or without Glide, but you have to guide Glide to not load at full resolution.
You can load smaller sized image via .thumbnail(), it accepts a full Glide.with... not including .into() OR there's a shorthand parameter which is just a percentage (in 0.0 ... 1.0), try the latter first. It should decode the image much faster, especially with a really small number like 0.1 and then when higher quality one finishes it's replaced.
So the simpler option is to add .thumbnail() to your current load. A more convoluted one involves to start loading a lower resolution image with .sizeMultiplier() at the same time the Fragment's view is created and then start loading the high resolution one when the ViewPager has changed page. This helps with peeking the pages.
Alternatively you can just use a .placeholder() while the image is loading so it's not empty space, but "something" there.
Regarding using ARGB_8888 (32 bit per pixel): if you increase the memory consumed by Bitmaps (compared to RGB_565 (16 bit per pixel) don't expect to get run out of memory later. Once you get it working with 565 you can try increasing, but until then it's futile trying.
Also look around the Glide issues, maybe you find something helpful.
I know that ,according to android docs, that if you have a big image. Then you scale it down to size of the image view you are loading it to (using the decodeResources and Options class).
Now my question is, lets say you want to load background picture and the source image is of similar size, do you just load the image? Or do you actually scale it down a bit and then using the FITXY to stretch it?
I am trying to avoid Out Of Memory exceptions here
Thank you
For some reason I can not load any image that has more than 200 pixels in either width or height without getting a OOM error. To fix this I lowered the amount of pixels on my images but now they all look blurry. Does anyone know the best way to load higher quality images without getting this error. Also I have tried manually recycling my bitmaps but when doing so it seems to just give me the out of memory error no matter what size the images are.
The inSampleSize of the BitmapFactory.Options class can solve your issue, Try to see the officiel android docs Loading Large Bitmaps Efficiently and you will get it work.