15

I'm building a very basic gallery on android, it shows the last image on the camera folder and the user can slide left to see the previous one.

I finished an implementation using a viewpager, and a pagerAdapter using sampleSize to scale images. My problem is that the implementation is nowhere as efficient as the default gallery app, every time you slide an image you have to wait around 200ms for the next one to load. So basically my idea on how to implement it is not working out.

How can I do this efficiently, and if possible with an implementation that allows zooming in and out later on?


This looks promising but I don't know how to implement it with files instead of drawables http://www.androidviews.net/2012/11/photoview/


EDIT:

I've managed to improve speed a bit using photoview (a hacked viewpager), however it takes too much to convert the filepaths to bitmaps or drawables.

I have tried these two methods suggested by dilix and iDroid Explorer:

// Method A
Drawable d = Drawable.createFromPath(imagePath);
imageView.setImageDrawable(d);

// Method B
Bitmap myBitmap = BitmapFactory.decodeFile(imagePath);
imageView.setImageBitmap(myBitmap);

But both produce error Bitmap too large to be uploaded into a texture. I need to get the image to the imageView as fast as possible and somehow bypass this error and maybe I'll get a decent speed. Right now I'm scaling the images and converting them to a drawable but it's not very efficient.

lisovaccaro
  • 32,502
  • 98
  • 258
  • 410
  • You can use Gallery http://developer.android.com/reference/android/widget/Gallery.html – Jaiprakash Soni Jan 29 '13 at 07:07
  • You must know that the lag you are noticing is because of the polling of files! So, if you notice that androidviews.net is very fast, remember that it is using drawables and not image files! – Sherif elKhatib Jan 29 '13 at 15:39

4 Answers4

3

Check this awesome website : http://www.androidviews.net/ and maybe this is what you want: http://www.androidviews.net/2012/11/photoview/

It has page scroll, zooming and panning as you need I have used it in my project with some modifications and lazy image loading. It is working exactly as you need.

Naveen
  • 1,703
  • 13
  • 22
  • 1
    I just tested it, it works great. But I've been looking into the code and don't see any way to implement it with image files instead of drawables. I'll start checking if I can combine it with my implementation but I don't think it will work. – lisovaccaro Jan 24 '13 at 01:27
  • I'm using the photoview implementation combined with `imageView.setImageDrawable(GetDrawable(imagePath, 150, 150));` to convert the SD card file paths to drawables. However it's still quite inefficient. Maybe there is a way to view.setImage with a file path? (No conversion required) – lisovaccaro Jan 29 '13 at 19:42
  • This lead me in the right path. I have to figure out how to do lazy image loading and maybe how to change viewpager animation if it's possible – lisovaccaro Jan 31 '13 at 19:54
  • Do you know how can I disable pinch open/close zoom? – VansFannel Jul 17 '13 at 16:13
1

1)

This looks promising but I don't know how to implement it with files instead of drawables http://www.androidviews.net/2012/11/photoview/

You have to store not list of drawables in you adapter, but links to files on your sd card and then load it.

2) But i can imagine that file instead of drawables won't be so efficient because to load from files you have to parse it from sd card.

I think you can save time by loading several images in your memory simultaneously (compressed) and when you swype to your othe image you'll already have the image and memory and while swyping you can start loading other image in memory.

When fling over the gallery you may not load images and load it after almost stopping.

It's the main problem: memory consuming vs performance.

UPDATE

I think better than exploring this by yourself will be exploring existing code of google gallery: https://github.com/CyanogenMod/android_packages_apps_Gallery

As i checked - they store cache (almost as i've said about loading multiple bitmaps) and store only resized images - seems to be efficient.

dilix
  • 3,761
  • 3
  • 31
  • 55
  • Maybe I misunderstood your first point, I have a list of files in my adapter but I have to convert them to drawables since I don't know any other way to add them to an image view I do something like this (`imageView.setImageDrawable(GetDrawable(imagePath, 150, 150));`). Is there a way to display the image without doing this conversion? It would probably save a lot of resources – lisovaccaro Jan 29 '13 at 19:39
  • You can load bitmap (compressed and you can load for example 3 at once - current, previous and next) and load this bitmap to the view like this: http://stackoverflow.com/questions/4181774/show-image-view-from-file-path-in-android – dilix Jan 30 '13 at 07:06
  • I just tried the implementation from the other question but I got error: `Bitmap too large to be uploaded into a texture (2560x1920, max=2048x2048)` it seems close though. Is this related to compression? I don't know how to load them compressed, do you know how to bypass this error? – lisovaccaro Jan 30 '13 at 08:03
  • I cannot tell yet but if this works I won't have to convert images to drawables and maybe I'll save a few miliseconds. btw I think I'm already loading 3 images at once since the viewpager preloads sibling screens automatically – lisovaccaro Jan 30 '13 at 08:04
  • "Bitmap too large to be uploaded into a texture (2560x1920, max=2048x2048)" - you device's screen is to small for such resolutions - it will be more efficient to resize bitmaps: http://stackoverflow.com/questions/4837715/how-to-resize-a-bitmap-in-android BTW don't forget to recycle your bitmaps to avoid memory leaks. – dilix Jan 30 '13 at 08:11
  • It was only suggestion, sorry if i don't help. Then you can check existing code of google app (check updated answer). – dilix Jan 30 '13 at 08:45
1

See the official documentation for a great example that will walk you through using bitmaps with a viewpager efficiently. You should use a cache of the images that have already been loaded, and the images should be loaded outside of the UI thread. You also want to scale the image to the minimum size needed for your display (usually powers of two - note that the image won't always scale to what you ask it to!) ViewPager also loads images in the background to prepare for the next slide, which is set with the setOffScreenPageLimit method (the default is usually good, I think it's 2.)

https://developer.android.com/training/displaying-bitmaps/index.html

ndw
  • 513
  • 6
  • 14
  • At first I thought the example was awful but it does allow for fast sliding. It takes for ever to start though. I'll see if I can implement it – lisovaccaro Jan 29 '13 at 18:58
  • I have been trying to get images files to load dynamically but it seems impossible to get them inside imageUrls which is final and static. Please check what I tried maybe you can figure out a solution: http://pastebin.com/raw.php?i=LDAwU7Mx – lisovaccaro Jan 29 '13 at 19:35
  • Did you mean to call pathsList, imageList? Then since imageUrls is a final variable you can only assign it once. You can use `public final static String[] imageUrls = imageList.toArray(new String[imageList.size()])` – ndw Jan 31 '13 at 13:23
1

I am not sure whether you got correct solution or not. But if you want to continue with your own implementation with your given link then:

http://www.androidviews.net/2012/11/photoview/   //this link is given in your question

And you can see this SO for how to convert file's path in to the drawable. Now, you get drawable of your specified file and implement on the link you have given.

I think that link will works nice.

Feel free to comments.

Community
  • 1
  • 1
Shreyash Mahajan
  • 23,386
  • 35
  • 116
  • 188