Achieve smooth scrolling for Photo Grid with thousands of images from disc
Asked Answered
B

2

6

I have a PhotoGrid with three photos on each row, implemented using UITableView.

I have an in-memory cache (using NSCache) which has a capacity for 100 images, so at one time I will be having at most 100 images in memory even though I have thousands of images on disc to show up in the Grid.

All my images are 4KB-20KB JPEGs.

So with this infrastructure, the images are continuously loaded and unloaded from NSCache when the user scrolls through the photo grid. With normal scrolling everything looks good, I get around 55-58 fps.

When the user starts scrolling faster back and forth, I have two cases:

  1. If I separate out the image loading task from main thread, I end up missing images on the photo grid, because my cells are displayed before the images are read into memory.

    (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, 0), ^{
            UIImage *image = getImageFromCacheForImagePath:imagePath;
            dispatch_async(dispatch_get_main_queue(), ^{
                cell.leftGridItem.imageView.image =  image;
            });
        });
    }
    
  2. If I have the images loading task on the main thread, there is a stutter. I get around 36-45fps.

    (UITableViewCell *) tableView:(UITableView *)tableView cellForRowAtIndexPath:(NSIndexPath *)indexPath {
        UIImage *image = getImageFromCacheForImagePath:imagePath;
        cell.leftGridItem.imageView.image = image;
    }
    

getImageFromCacheForImagePath:imagePath gets the image immediately from NSCache if it existed, if not, the image is loaded from file and is set into NSCache for later usage, but I set the limit of NSCache to 100.

Things I tried/tweaked:

  1. Avoid clipsToBounds for grid image views.
  2. Loading images on background thread.
  3. Use of NSOperation Queues.
  4. Loading images in batches of 100 (works, but with fast scrolling, image loading time was delayed).

I am trying to achieve the same feel as native Photos app.

Your suggestions are appreciated.

Botti answered 7/1, 2013 at 6:54 Comment(2)
Please review the code in your question. The formatting needed help, and when done revealed some problems (see the code ^{ which looks like it should start a new code block but doesn't seem correct to me). We tried to help you get it formatted right, but it's not really clear.Kittykitwe
I wonder if they aren't generating thumbnails off-line, like at import time, and then the small size of the thumbnails gives them a significant advantage for main thread loading.Pham
T
0

I was also facing the same problem few days back, so GitHub is the best place to search for open source solutions, so try out these links.

Check PF-GridView or DTGridView.

also Take a look on AQGridView , How to Write a Custom Image Picker like UIImagePicker ,

Just need to do bit manupulation according to our need and it works like a champ.

Tocsin answered 7/1, 2013 at 7:33 Comment(1)
thanks for suggestion, the problem am facing is more towards cleverly and timely loading of images from disc to memory so that I won't use much memory but still show up images on grid view with smooth scrolling. Just like native Photos app, even with thousands of photos they have smooth scrolling as if all the images are in memory. I am trying to figure out, how they are handling it.Botti
C
0

I have implemented a smooth scroll table with more than 700 images. The key was not only to load images in background but also to resize it in background to perfectly suit the container. Apperently resizing is too heavy operation to do it in the UI thread.

Cicely answered 12/7, 2013 at 20:50 Comment(0)

© 2022 - 2024 — McMap. All rights reserved.