3

I have an image that I would like to display in my iOS app. To conserve memory, I would like to display the lowest possible resolution that still matches the number of physical pixels on the device

For example, could be displayed as a square 1/4 the height of the device. So the sizes would be as follows

iPhone 4s        240x240 px

iPhone 5/5s     284x284 px

iPhone 6          334x334 px

iPhone 6+        480x480 px

I've looked into asset catalogs, but I don't see any way to have a different image for iPhone 4s, iPhone 5/5s, and iPhone 6 (they are @2x). The only difference is iPhone 6+ (@3x).

I've also tried adding the Retina 4 2x option, but that only gives a different icon for the iPhone 5/5s - there is still no way to differentiate between 4s and 6.

enter image description here

I understand that I could choose the image programmatically based on the device, but asset catalogs only downloads the necessary images to the users device (not sure if that is true, I remember reading something about it, though), making the application take up less storage. It would be inefficient to include four images, if only one will be used.

Is there any way to use a different image resolution for every iOS device with a different amount of physical pixels?

Note that I'm not asking about scaling the image, but about getting the correct resolution used (a different image for every device), so less RAM will be taken when it is displayed.

Community
  • 1
  • 1
Jojodmo
  • 23,357
  • 13
  • 65
  • 107

2 Answers2

2

I ended up just creating a different file for every device, and naming them imageName@size, so for an image of a dog that is 128x128, the file would be named dog@128.

Here's the code that I used to do this

func getPNGImageForSize(size: Float, named: String) -> UIImage?{
    //the image size will be measured in points, which is the unit that is used
    //when setting the frames of UIViews. To turn this into pixels, it must be
    //multiplied by the screen's render scale (on an iPhone 6+, 1 point is equal
    //to 3 pixels, or 9 pixels in 2 dimensions (3^2).
    let scaled: Int = Int(ceil(size * Float(UIScreen.mainScreen().scale))
    let imageName: String = "\(named)@\(scaled)"

    //ofType set to png, because this image is a PNG
    let path = NSBundle.mainBundle().pathForResource(imageName, ofType: "png")

    return UIImage(contentsOfFile: (path ?? ""))
}

And to call it, I simply use

getPNGImageForSize(Float(self.view.frame.height / 4), named: "dog")

which would result in the following images, depending on the device

iPhone 4s           dog@240.png

iPhone 5/5s        dog@284.png

iPhone 6             dog@334.png

iPhone 6+           dog@480.png

This could also be altered to work with non-square images, named imageName@width-height

func getPNGImageForSize(width: Float, height: Float, named: String) -> UIImage?{  
    let scaledWidth: Int = Int(ceil(width * Float(UIScreen.mainScreen().scale))
    let scaledHeight: Int = Int(ceil(height * Float(UIScreen.mainScreen().scale))
    let imageName: String = "\(named)@\(width)-\(height)"

    let path = NSBundle.mainBundle().pathForResource(imageName, ofType: "png")

    return UIImage(contentsOfFile: (path ?? ""))
}
Community
  • 1
  • 1
Jojodmo
  • 23,357
  • 13
  • 65
  • 107
1

You need to set your image as to what it may look like in iPhone6+ which will consume the @3x images, then scale down to its @2x image size which will be consumed by iPhone4S to iPhone6 devices and then further scale your image to @1x which earlier versions of iPad devices use.

Create 3 different images with 3 scales of @1x @2x and @3x.

there are 3 only, Older iPhone - 3S, 4, non retina iPad all consume @1x images, whereas iPad Air, iPad retina , iPhone 4S - iPhone 6 uses @2x and iPhone 6+ uses @3x FYI I have answered this question before here is the link

Here is another good blog about image scaling in IOS devices (all of them)

EDIT

and about clearing your doubt about how come iPhone5 and 6 use @2x images. Well iPhone5 uses the same image that is for iPhone6 i.e @2x images despite of the height as iPhone5 scales down @2x into its own limit hence there is nothing to worry about this. Xcode takes care of this quite efficiently.

Community
  • 1
  • 1
Saheb Roy
  • 5,899
  • 3
  • 23
  • 35
  • This does not answer the question, which is asking how to have a different image for **EVERY** iOS device – Jojodmo Sep 10 '15 at 05:46
  • have edited the answer if it still confuses you then plz comment will be happy to clear the confusion – Saheb Roy Sep 10 '15 at 05:48
  • Still, there are only 3 options (one of which is only for older iphones, so actually 2) of places to store the images - to have a different image for every device, there needs to be 4, because although some devices have the same scale factor, each device has a different amount of pixels – Jojodmo Sep 10 '15 at 05:49
  • There is no getting around with this, if you want to use image assets you got to let xcode choose the device and select the correct image for you. OR you can choose separate storyboards to load each storyboard with each unique image sets for different devices.. I have edited the answer once again for your understanding – Saheb Roy Sep 10 '15 at 05:50
  • exactly - the point of the question is how to get around this – Jojodmo Sep 10 '15 at 05:50