Image scrolling app - bitmap too large to be uploaded into a texture - android

I am working on a very simple app that shows one jpg, which is scrollable on vertical axis.
I would like this image to be very large(20000x1000 px), however, when I try to run the app on my device, it says that "bitmap too large to be uploaded into a texture".
Is there a way to display the image of such size in an android app?
If not, would it be possible to divide the image into segments, and after I scrolled to the bottom
of one segment, I would proceed to another?

To quote the answer for your question here:
All rendering is based on OpenGL, so no you can't go over this limit.
Note that this would take a huge amount of memory. With such big
images, if you want to zoom in out, and in a mobile environement with
heavy memory constraints, you should setup a system similar to what
you see in google maps for example. With the image split in several
pieces, and several definitions.

You could split the images into let's say 128x128 chunks. Add them to an array, and loop the array to create and fill an ImageView with the image that is currently served.
some pseudocode would be: (excuse me, I've been programming a PHP application the past few days)
Private BitMap[] imageArray = {your bitmaps from internal or external storage};
For(BitMap bm in imageArray) {
// create a new image view here, use the correct layout params or use a parrent grid view.
imageView.setBitMap(bm)
}
now once again, I am 0% sure about that pseudo code, but it should help you along.

Related

40+ ImageButtons on one screen?

For last 10+ hours I try to get a large (40+) amount of images (in ImageButton format) on a single Android screen without out of memory errors. The activity I work on is an image picker for a coloring book app. Images are of various sizes in the range of (500 to 1200)x(500 to 1200), PNGs (if that matters).
I have tried:
Horizontal Scroll View with images added from the code. The result is slow (I do it on UI thread) and consumes large memory space.
Horizontal Scroll View with images added from the code via AsyncThread. The result is fast but still consumes large memory space. I like the user experience of this one the most!
Grid View and List View - both are very choppy (testing on first Nexus 7). Memory usage is better.
What I am considering
View Pager - first results look better than Grid View from performance perspective (I have not completed it to the moment to assess the memory usage but it should be better from what I understand). Yet, I dislike the user experience and prefer a scrollable list of all images.
Conversion of my resources to JPG (will that get rid of Transparency byte?)
Downsizing the images to max 500x500px
None of the solutions seems as good as the Android Photo Gallery app available on all devices. This experience is what I would love to mirror. No idea how this is done though :(
Two questions.
What is the best way to get such thing (40+ Images scrollable on single screen) done? Is it really ViewPager? ScrollView with AsyncTask and well thought images resolution? Something I have not tried yet?
What is the memory limit I should try to keep below? Looking at Android heap size on different phones/devices and OS versions it seems to be 256 MB, is that fair assumption?
Thanks. Have a great weekend!
PS. On iOS all works like charm when I add all the buttons into a scroll view :(
Some basic calculations reveals your problem:
40+ images at 1200x1200 = approx 57MB, the comments are correct you need to subsample (i.e. thumbnail) the images or use a library such as the Universal Image Loader. Converting to JPG doesn't matter. That is a compressed storage format, the memory required to display the pixels remains the same.
There is a Android Developers article on Loading Large Bitmaps Efficiently with sample code. The following steps are covered in more detail in the article Android Bitmap Loading for Efficient Memory Usage.
The basic steps in loading a large bitmap are:
Determine the required size (from a known size or determining the
size of the target View).
Use the BitmapFactory class to get the bitmap’s size (set inJustDecodeBounds in BitmapFactory.Options to true).
Calculate the subsampling value and pass it to the BitmapFactory.Options setting inSampleSize.
Use the BitmapFactory to load a reduced size bitmap.

Load multiple large images in single ImageView

I have multiple large images and I would like to use these in such a way that it would allow users to do continuous panning. I couldn't stitch all the images into one image as it would give memory limit error. Also I want to compress the images. I believe one option is to place the images in a virtual grid shape and show image based on current viewport & touch position (it might have some issues when switching between images). I was wondering if there is any other easy ways to solve this.
You can split the images into smaller ones and load only the images currently visible on the screen and probably the next one to provide smoothness while panning. So if you have 6000x4000 you may want to automatically split them into 24 images 1000x1000.

Why are my imageView animation so lag in big screen android device

i'm android beginner and trying to program an android app that can dynamic add imageViews to the basic RelativeLayout. It's perform well in my android device but perform poorly in my friend's device which has a big size of screen. I googled for very long time but can't find the solution. Below are part of my code, can anyone help me?
ImageView im = new ImageView(GameActivity.this);
im.setImageBitmap(BitmapFactory.decodeResource(getResources(),R.drawable.image);
RelativeLayout.LayoutParams param =new RelativeLayout.LayoutParams(imageWidth,imageHeight);
wholeView.addView(im, param);
im.setX(x);
im.setY(y);
im.setRotation((float) (-15 + Math.random() * 30 + 90));
dealAnimation = new TranslateAnimation(-x,0,-y,0);
dealAnimation.setDuration(500);
dealAnimation.setRepeatCount(0);
im.startAnimation(dealAnimation);
Where is the size of the bitmaps that you are addding to each ImageView? Which is the total amount of bitmaps that you are adding and in how many time do you performe this operation?
When you say "my device" and "big size of screen", what exactly you mean?
Maybe you're trying to load a very large bitmap? Another point is that you are using the class BitmapFactory which means that you are decoding the bitmap. A large bitmap will use a very large amount of memory when decoded.
Start with appropriately scaled bitmaps, using the various drawable folders to load images (drawable-hdpi, drawable-xhdpi, etc) with a proper initial scale combined with a good distribution of your layouts for each screen size (layout-large, layout normal, etc) to avoid re-scale the bitmaps. And instead use BitmatFactory, try with im.setBackgroundResource(R.drawable.image);

Loading tall images from url in slivers preventing whole image from loading into ram

I am looking for a library or some idea on how I can load an image by parts from the disk or a url straight to the disk then in parts again to the ram. So the two ways I see that this can be done is loading the whole image onto the disk by reading and writing it from the url directly using the ram only for the buffer then when the image is on the disk some how creating bitmaps of only parts of the image, that way I DO NOT load it all and putting those in a ListView.
The issue is that I am dealing with extremely long images (10K + pixels long w/ a width of 4-600) and they hog up lots of ram if loaded all in one bitmap. I can not just scale them down like the Google android tutorial does in the handling large bitmaps section as that results in a width too small to deal with. So if I can somehow generate small bitmap slivers on the disk I can use them by loading them in a ListView preventing loading the image as a whole into ram.
Right now I am breaking the long images into slivers from a bitmap and I realized that that isn't really accomplishing what I am trying to do as the whole image is loaded into a bitmap in memory and is then broken up, then GC (So I am using up the full abmount of ram anyways). I am testing on a new top of the line android phone and the app works fine, but the heap size reaches 80mb+ with the larger images temporarily in ram as it breaks down the bitmap and this will be an issue with devices that have lower heap limits
You can try using this class, support from 2.3 http://developer.android.com/reference/android/graphics/BitmapRegionDecoder.html
If you are using Java you can work with InputStreamReader and OutputStreamWriter. Method read() accepts the buffer as one of the parameters, its length can be anything suitable. Of course you can create a new file for each buffer being written.
Is it what you're looking for?
edit
well its not. have you seen this Strange out of memory issue while loading an image to a Bitmap object ?
If you have control over the server from where you are fetching data, throw in another field in your response, such that it returns a thumbnail/smaller image. The server can then generate the required thumbnails for you, without you bothering about it.
Decoding bitmaps on the fly might be expensive, most of the times. If you can't change anything on the server, download and save the images, and after saving, generate their corresponding thumbnails and save them as well. In your list, use the thumbnails. Also, save the information about which images have been cached, and whose thumbnails you already have. This might look like a lot of work, but depending on the use case, this can be a better approach dealing with large images.
Problem with downsizing?
Well, you can come up with some kind of logic as to generate thumbnails, based on the original size of the image. For longer(vertically long images), you could use BitmpapRegionDecoder (http://developer.android.com/reference/android/graphics/BitmapRegionDecoder.html) as #Binh Tran has suggested.
Try maybe encoding the image to make the size small.

Merging multiple picture to form one complete picture in Android

i would like to know whether is it possible to merge several images to form one complete image. For my case, is a floor plan that is split in 18 small images and i would like to merge them into one. I had one idea but not sure whether is it workable. My idea is this:
I would first place the top left most image first, with the x and y coordinates as (0,0).
Next for the subsequent images (right/bottom of this first image), using the width and height of the image, i would find out the coordinates where the next image would be placed. Doing this i presume would required 18 ImageView to achieve that.
Btw, these 18 images are .gif format and so do i need to like convert them to Bitmap or something before i can display them using ImageView?
You could merge the images to a bigger images by drawing the small images to a canvas associated with the resulting big bitmap
Canvas c=new Canvas(result_bitmapenter);
and then draw your small images onto the canvas
c.drawBitmap(small,...);
But that might not be the best way as big images eat lots of memory - perhaps you should concider dynamic loading instead of merging then
Yes its possible create a Bitmap object large enough to hold the whole floor plan and use Canvas to paint them into to the large bitmap. Be sure to cache it or you'll be recreating it every time and you'll have to convert it to png for compatibility with older devices.

Categories

Resources