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.
Related
So my app needs to have a maximum of 50 images on the screen at the same time in a FrameView, they need to be placed on top of a base image. If I put these images into drawable, the app crashes after a few images are placed with an OutOfMemoryError. But it works when I put the images in mipmap for some reason without crashing. So I placed them all into the mipmap folders. The images are VERY small too, the largest among them is 2.2 KB and the smallest is 398 bytes. The app works as intended, but performance is horrible after you place a few images onto the screen. The first few images will load quickly, but as you continue to place images onto the screen it gets progressively slower to the point where it may take multiple seconds to place the image onto the screen. I'm just using an ArrayList to put all the Drawables in, and then another ArrayList to put all the ImageViews and I load them into the view within my onTouchListener. Here's an idea. The index is used to decide which image is to be inserted:
drawableOverlays.set(index, getResources().getDrawable(R.mipmap.exampleImage, null));
imageOverlays.get(index).setImageDrawable(drawableOverlays.get(index));
frame.addView(imageOverlays.get(index));
I've also tried using Glide and Picasso and those loaded in even slower. Am I approaching this wrong? Is there a more efficient way to accomplish this?
The best way is create a RecyclerView with ImageViews as items, and then load the images with Glide or Picasso, any of those libraries will give you the best performance
High/medium resolution photo takes time to load from drawable and affects application performance, whereas low resolution photo looks blurred; I want to use high resolution images but not compromise with the performance, How to do that?
I am trying to set a high resolution background image of layout login from drawable, so when switching between components of the same activity lagging occurs.
For instance: switching between field email to password, keyboard appears/disappear in slow motion.
If I were you , I would use the Glide library. Its faster than Picasso and ideal when you want to load large images.
From the github documentation :
Glide's primary focus is on making scrolling any kind of a list of images as smooth and fast as possible, but Glide is also effective for almost any case where you need to fetch, resize, and display a remote image
Yes, use Piccaso. It will adjust and load a correct image size depending on your device and size of imageview.
Hard to know what you need, but you can use a FrameLayout to download multiple pictures in the background and set them invisible till you need it with android:visibility attribute.This solution is for one activity. Asynchronous work and cache can be the answer.
You should consider resize your pic anyway, users prefer see the pic than wait and quit, they know the limitations of their devices (so does android ;-).
I need to load a lots of images (3500 images) to my android app (and then I will rotate with each of them in the application). But when I load each of them separately (creating new ImageView which I add to the array) then it takes about 10 seconds to load. I have tried to inflate them from XMLs since there is only 8 different images which I use but no visible changes.
I would be really grateful for any advice how to load it faster.
EDIT: I am creating a grid of hexagons, each hexagon is consisted of 6 triangles (this way I need to store only 8 different triangle images instead of storing image for each different hexagon). After the grid is loaded user can resize it. I need to load all the grid cell at once because there are many constrains between them. Also only operation I will do with the hexagons is to rotate them.
You can use cashing for bitmap images, the following tutorial link is helpful.
http://developer.android.com/training/displaying-bitmaps/cache-bitmap.html
I have a bunch of images that are displayed in a list view (one per row). The image file I have is a pretty large resolution so I'll need to scale it down to be shown in the list view.
So, my questions is...is it faster to store two images (one regular and one thumbnail) so nothing has to be scaled on the fly OR is it faster to simply allow android to scale this larger image upon list creation?
Thanks!
Nick
The best approach depends on your particular use case. If you really want to resize the image to a thumbnail level (e.g. 150x150) and don't plan to have more than about a 30 images to display, the best approach would be to just keep a cache of the Bitmaps in memory without writing them to disk (at a cost of about 3 MB of memory for the 30 images). This way your ListView won't stutter while you scroll images in and out of the screen. You can of course keep the full version and display that when the user taps on the ListView item.
If you want to display a higher resolution version in the ListView, then you might have to get creative. Remember that you don't have much time to render each individual ListView cell to keep a smooth scrolling experience, and that decoding a large image file will take time, even if you're downsampling it and resizing it; the initial decoding time is the same, the only difference is the size in memory. In this case then it might be convenient to keep both the original and the smaller size version in disk to reduce the stuttering as you scroll.
Store two images to avoid your users having to wait to get the fullsize of every image even though all they're looking at are thumbnails, unless the images are bundled in with the app (i.e. not downloaded on the fly).
For anyone who's wondering, the gallery is http://www.spore.com/sporepedia.
My app uses the Spore API to get the 100 newest creations, then displays them in a GridView. The text data about the creations is easy to store, but the images present a problem.
As far as I know, I can either keep the images in a Hashtable or grab them every time they are viewed. Neither of these will work - the Hashtable quickly presents an OutOfMemoryError, and the constant reloading causes a lot of load on the server and a lot of lag on the client.
Is there a better way to store the images?
First Don't get 100 at a time, there is no way your displaying 100 images in a gridview and having them be a usefully visible size. Retrieve the images asynchronously and get a screen full or a screen and a half at a time. I'm guessing you can display 6 to 9 images of a decent size per screen with supporting text/UI elements, you may even want to choose how many to display based on the handsets screensize/resolution. So you should probably be getting 9 to 12 images at a time.
Second, i don't know what resolution these images are coming in at, but it sounds like 'big'. If the API supports it receive only a thumbnail version for you grid view. If not, what i would probably do is: when you receive an image from the API, first create a new image scaled down to the size needed for your thumbnail that goes into the grid view, keep this in memory. Then create a new image scaled down to the size you would need for your 'detail' screen (if you have one) and cache this to the SD card and free it from ram as well as the original source image, this scaling should probably occur in a separate thread to avoid it impacting the responsiveness of your UI thread. Depending on the usage pattern, I would probably also cache the thumbnails to the SD card so it would be cheap to free the ram they use in onStop/onPause and reload them in onStart/onResume. IT also sounds like you downloading a 'top 100' or something of the sort. Since i wouldn't expect an entires new top 100 on every application use you could save a lot of network traffic by caching the images and information to the SD card and only downloading new entries each time the program runs.
Alternatively a process like:
Receive Image -> Scale in place to detail size -> cache detail size -> scale detail size to thumbnail size in place -> display thumbnail in gridview while caching thumbnail asynchronously
Would use even less memory since there is only ever 1 copy of the image in memory, but it would slow the response of the gridview as the image has to be scaled twice before it gets displayed. It may be fast enough to not matter or you may be able to play tricks with the grid view by having it display the large image (scaled internally) while the thumbnail is generated in the background, switching the gridview to the thumbnail when its ready. You'll just have to try it to determine if its fast enough.