3

I have PNG images that range from 2MB to 12MB in size. I'm loading one of these images into an imageView using SDWebImage via the following code in my viewDidLoad:

self.imageView.contentMode = UIViewContentMode.ScaleAspectFit
self.imageView.sd_setImageWithURL(NSURL(string: imageURL))

It can take as high as 17 seconds to load this image onto the view. Am I doing something wrong here? I'm only loading one of these images into my view, so I did not think it would take this long. Any other things I can do to load the image faster?

Is the only option creating a smaller image to load?

JK140
  • 775
  • 2
  • 10
  • 19
  • Have you tested this in different network? – user3581248 May 08 '17 at 23:42
  • Not much you can do. If the size of image is 12MB, it takes 12 sec to download the image even if downloading speed 1MB/sec. – jokeman May 08 '17 at 23:52
  • @jokeman Thanks for the reply. These are images that I'm uploading from my iPhone 6 plus, so nothing out of the ordinary – JK140 May 08 '17 at 23:56
  • Where the images come from doesn't make a difference, does it? – jokeman May 09 '17 at 00:23
  • SDwebImage library do the catching .....It's already optimized ....The loading at first time it may take time .... They have provided also a method in which you have to pass two parameters ,`NSURL` and `UIImage` that is the placeholder image...... You should use that method – Dhiru May 09 '17 at 02:52

4 Answers4

0

Compress the image and load it.. if you are accessing this through network make sure you have enabled caching to make the loading faster

Sharath
  • 275
  • 1
  • 18
  • Thanks so much for the answer! Can you explain in more detail how to compress the image before I load it? Is this something I can do in Swift or a back-end task? Also SDWebImage provides caching by default. When I re-load the view, it loads the image instantaneously. It's only the initial load that can take up to 17 seconds. – JK140 May 08 '17 at 23:55
  • Its not good idea to load such a large image... its better you compress and the server side and send to client ... so bandwidth can be save... compressing on server side depends on the language that you use in srevr...I am sure.... the language will have compression libs – Sharath May 09 '17 at 08:55
0

We have something called intervention that we have at our backend. It provides us with a URL in which we can scale image by providing a width and height after the URL

guard let url = imageURL else { return }

var smallURL = url + "/" + "(20)" + "/" + "(20)"

So, What I do here is that I load the image with size (20x20) first and show it as blurred image and when the image with actual size is loaded I replace it with original Image.

That way it is a good UX because User does not have to wait for the image to load instead it gets a impression that image is loading.

And all these things are done in extension of image view so, you can directly call it as :

imageView.setImage(imageURL: "https://i.stack.imgur.com/GsDIl.jpg")

extension UIImageView {
  func setImage(imageURL : String?,size : CGFloat = ScreenSize.width ){


    guard let url = imageURL else { return }
        var originalURL = url
        var smallURL = url + "/" + "\(20)" + "/" + "\(20)"

    let actualImageUrl =  URL(string: name)
    let smallURL = URL(string: smallName)
    self.backgroundColor = UIColor.lightGray.withAlphaComponent(0.5)



    self.yy_setImage(with: smallURL, placeholder: nil, options: .showNetworkActivity) { (image, _, _, _, _) in

        guard let _ = image else { return }

        let blurredImg = image?.applyBlurWithRadius(0.5, tintColor: UIColor.black.withAlphaComponent(0.4), saturationDeltaFactor: 1.0)
        self.image = blurredImg
        self.yy_setImage(with: actualImageUrl, placeholder: blurredImg, options: .progressiveBlur, completion: { [weak self] (image, url, type, _, _) in
            self?.image = image
        })
    }
  }
}

Instead of using SDWebImage I have used YYWebImage it provides more features and It is based on SDWebImage.

Hope it Helps!!

Agent Smith
  • 2,873
  • 17
  • 32
0

Some of the other suggestions like caching and blurred image preview are good but I would suggest, in addition, you consider optimizing the images better in the first place.

Check out my answer to a related question about reducing app file size by reducing image size,

Reducing iOS App file size

PNG files are the preferred image format for iOS but you can also use JPEG taking a small hit in load time but the gain in file reduction often outweighs this by an order of magnitude or more. Basically, if the image contains large regions of continuous tone like photos, then JPEG is likely better. You can play in Photoshop but the $7 (on sale from 14) Lossless Photo Squeezer does a great job with no effort.

Even if PNG you can save size by dropping the bit depth. This is how Loss Photo Squeezer works dropping to 8 bit. If you do not transparency you can drop the alpha channel or if you need limited you can use a 1-bit alpha channel out of photoshop. If you want to go hardcore, it is possible to use 8 bit JPEG with an 8-bit alpha channel. See

http://calendar.perfplanet.com/2010/png-that-works/

You can also play with bit depths lower than 8 for some images.

If you want to go really hardcore consider using WebP. There are a few open source iOS implementations such as https://github.com/seanooi/iOS-WebP

You might also want to look at the resolution. retina images are great for fine detail like text but I often use 1x resolution for images even on a retina display for photographs. This works out well because if you need the resolution to read text than there is a good chance that the PNG will compress very well anyway.

IF you have an image that has aspects of continuous tone appropriate for JPEG and some area such as text that is more appropriate for PNG, you can go crazy and break the image into a JPEG and an 8-Bit PNG with an alpha channel and combine the two images after download.

Community
  • 1
  • 1
David Berger
  • 766
  • 5
  • 10
0

If you are trying to download a thumbnail image from the back-end you can try adding the context parameter in your SDWebImage call.

yourImageView.sd_setImageWithURL(withPlaceholder: nil, context: [.imageThumbnailPixelSize: yourThumbnailSize])

Add some constant image thumbnail pixel size as shown above.

iPhoneDeveloper
  • 958
  • 1
  • 14
  • 23