I am developing portrait resolution app which will support all iPhone screens. I am not scaling so i have to cater every Screen size. iPhone 6 plus have 1242 x 2208 (#3x) for portrait and iPhone 6 have 750 x 1334 (#2x) for portrait.
Normally i would create full width image graphics in 320#1x, 640#2x and 960#3x. But now it wont work. Do i have to make full width sized images separate for every resolution?
Like i would create 640#2x for iPhone 5s or earlier and 750#2x for iPhone 6 and 1242#3x for iPhone 6 plus.
Do i have to make different images for every resolution? Am i going in right Direction or there is a better solution?
The iPhone 6 and iPhone 5 uses the same #2x images, but as the resolution is different on both the devices it's best practice to get the different images for both.
On iPhone 6, if the image of iPhone 5 will be loaded then you will see some distortion.
On other hand, if you have image of 750 x 1334 (#2x) for iPhone 6 and if you will load that ion iPhone 5 or 4 then you will see squeeze image as it is of higher resolution.
But the problem is that if you put both iPhone_5#2x and iPhone_6#2x then Xcode will not that which image to be loaded on which device. So, for that I have made a function to differentiate the images at runtime.
//MARK: Load Images for particular device
func getDeviceSpecificImage(imgName: String) -> String{
var imageName: String?
switch UIScreen.mainScreen().bounds.width{
case 320:
imageName = String(format: "%#_5#2x", imgName)
case 375:
imageName = String(format: "%#_6#2x", imgName)
case 414:
imageName = String(format: "%#_6+#3x", imgName)
default:
break
}
return imageName!
}
Hope this helps!
Related
I have already added all images in three format like test.png, test#2x.png, test#3x.png for IOS in resources folder, still on big resolution screen like ipad it shows default one test.png.
I am not getting why this is happening. Am I missing something from code side.
EDIT :
sorry my mistake. my question was wrong.it shows different image but in small size.
i tried 3 different images with same name having #2x,#3x extension. so i come to know that in ipadPro(9.7 inch) it shows #3x image while in iphone5(which lowest screen resolution simulator in my mac) it shows # 2x image.
so how could we decide which screen resolution will take which image?and how can we decide their size.?
Depending on the device, you accomplish this by multiplying the number of pixels in each image by a specific scale factor. A standard resolution image has a scale factor of 1.0 and is referred to as an #1x image. High resolution images have a scale factor of 2.0 or 3.0 and are referred to as #2x and #3x images.
Suppose you have a standard resolution #1x image that’s 100px x 100px, for example. The #2x version of this image would be 200px × 200px. The #3x version would be 300px × 300px.
iPhone X, iPhone 8 Plus, iPhone 7 Plus, and iPhone 6s Plus support 3x
resolution. iPhone 8, iPhone 7, iPhone 6/6s and iPhone 5s/5c support 2x
resolution. All other iPhone devices support 1x resolution.
Consider following sample set of images for view with size 10 points and how do iOS system selects device resolution specific image.
#3x -> 3 * (10px x 10px) = (30px x 30px) // iPhone X, iPhone 8 Plus, iPhone 7 Plus, and iPhone 6s Plus
#2x -> 2 * (10px x 10px) = (20px x 20px) // iPhone 8, iPhone 7, iPhone 6/6s and iPhone 5s/5c
#1x -> 1 * (10px x 10px) = (30px x 30px) // All other iPhone devices
Note: You don't need to do any code (setup) to assign device resolution specific images. Just add images for all (1x, 2x and 3x) types of resolution in your image set. iOS system automatically chooses/selects device resolution specific image from the set of image.
Look at this document of Apple: Image Size and Resolution
Here is nice tutorial for easy understading: DESIGNING FOR THE NEW IPHONE SCREEN RESOLUTIONS
I am using a storyboard as launch screen.
It has a full size UIImageView for artwork and a language dependent UILabel rendered over it.
I do have .png files for all possible iPhone screen sizes (iPad not necessary).
The artwork contains a circle that looks distorted when I use the same image for iPhone 4s and iPhone 5.
Approach 1
In the LaunchScreen.storyboard, I add an UIImageView for all iPhones and use an imageSet, that is defined in Assets.xcassets.
When I do this, the image#2x of the image set is used for iPhone 4s and for iPhone 5 5s. One of both looks bad, because iPhone 4s and 5 have different heights.
I am not aware that I can use size classes in the storyboard to distinguish between iPhone 4s and iPhone 5. Or can I?
Approach 2
create a launch image set in Assets.xcassets, which can hold all necessary image sizes.
I can't select this launch image set in the UIImageView as image.
Question
In a full size UIImageView in a LaunchScreen.storyboard: how do I display different pngs for
iPhone 4 + 4s 640 x 960 pixels
iPhone 5 + 5s 640 x 1136 pixels
iPhone 6 + 6s 750 x 1334 pixels
iPhone 6 plus + 6s plus 1242 x 2208 pixels (portrait and landscape)
The main problem appears to distinguish between 4 + 4s and 5 + 5s.
a circle that looks distorted when I use the same image for iPhone 4s and iPhone 5.
The problem is with the content mode of the image view. Use a content mode that does not stretch the image out of its aspect ratio.
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.
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.
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 ?? ""))
}
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.
iPhone 4 and iPhone 6, when using image cassettes in a xib, use the same #2x image. Is it possible to use different images for each and not use scaled mode for windows 6/6+? I am trying to use a full screen image for each and the iPhone 6 image doesn't scale down correctly, and the iPhone 4 image doesn't scale up correctly.
For the launch image you can use the assets folder with the device specific launch images.
Here you can set the Retina HD 4.7 Launchscreen for the iPhone 6
1x = 320 x 480
2x = 640 x 960 - iPhone 4
Retina 4 = 640 x 1136 - iPhone 5
Retina HD 4.7 = 750 x 1334 - iPhone 6
Retina HD 5.5 = 1242 x 2208 - iPhone 6+
EDIT
Go to the General Settings Of your project and check your settings make sure you have selected the assets folder. Remove the Launch Screen File text.
I'm almost done building my first iPhone app and am trying to add a background image, and am finding it a little confusing, because nowadays there's like 3 or 4 different size screens among the different iPhone versions, with different resolutions to boot.
So while I'm aware of the whole image#2x.png thing, I still don't know what I really need. If I want my app to run on iPhone 4/4s, 5s/5c, 6/6+, how many different versions of a background image do I need, and at what sizes and resolutions?
I have googled around and have not found any cohesive answers up to date for 2014.
Also, if the iPhone 6 is 1334x750 #3x, does that mean I'm supposed to include a 4002x2250 background? And then for the 1920x1080 iPhone 6+ #3x, a 5760 x 3240 image? That's MASSIVE! I feel like I must be understanding this incorrectly.
If you want to support native resolution of iPhone 6/Plus, you need to add launch images (prior to iOS 8) or launch screen xib (iOS 8).
iPhone 4/4S: 640 x 960
iPhone 5/5S: 640 x 1136
iPhone 6: 750 x 1334
iPhont 6 Plus: 1242 x 2208
That means you need to prepare 4 launch images with above resolution if you want to support these devices. You can use iOS simulator to capture screenshots with different resolutions. Your app will run in compatibility mode on new resolution devices if it can't find the launch image of the specific resolution. compatibility mode means your view will be scaled to fit the new screen size when still have the same logical size.
EDIT:
I think op misunderstands what do #2x and #3x mean. The resolution of iPhone 6 is 750(pixels) x 1334(pixels), 326 pixels per inch. This is the REAL resolution. And 375(points) x 667(points) is the logical size if the native resolution is supported. iPhone 6 Plus's resolution is 1242(pixels) x 2208(pixels), 401 pixels per inch and the logical size is 414(points) x 736(points).
This is how images with different resolutions work on iOS device:
Let's say you want to run your app on iPhone 4s, iPhone 5/5S, iPhone 6/plus. First thing you should do is to provide 4 launch images to support native resolutions of these devices. When iOS launch your app, it will check if the app provides the right launch image to support the native resolution of current device. If iOS finds it, then use that in launch time and the logical size of screen is right, your app runs as normal. Otherwise, your app will run in compatibility mode in which all of the views will be scaled.
Suppose there is an image named foo.png in your app of which the logical size is 100(points) x 100(points). You want this image looks same in all the above devices. You should provide 2 versions of this image. One is 200(pixels) x 200 (pixels) and should be named foo.png#2x and the other is 300(pixels) x 300(pixels) named foo.png#3x. If you load this image with [UIImage imageNamed:#"foo"], on devices except iPhone 6 plus, the app will load the image named foo.png#2x. Otherwise the app will load foo.png#3x and sample it down to 300 * 84%(pixels) x 300 * 84%(pixels).
And if you load an image from an url and need to render it on the runtime. Let's say the size you get is {width:100, height:100}, the scale is 1.0. This means the REAL size of this image is 100 * 1.0(pixels) x 100 * 1.0(pixels. If you don't want it to be scaled, you need to calculate the logical size yourself. You do it like this:
UIImage *image = ... // you get it from an url
CGFloat scale = [UIScreen mainScreen].scale;
CGFloat width = image.size.width / scale;
CGFloat height = image.size.height / scale;
CGRect frame = CGRectMake(50.0f, 50.0f, width, height)];
UIImageView *imageView = [[UIImageView alloc] initWithFrame:frame];
imageView.contentMode = UIViewContentModeCenter;
imageView.image = image;
[self.view addSubview:imageView];
I think the easiest way to do this is to use an image that fits on iPhone 6+ and then simply set UIImageView's contentMode to UIViewContentModeCenter. I think it's that one at least, the result should be that on iPhone 6+ you have a centered image but on the other screens you simply get a part of the image.
The downsampling of the iPhone 6+ means that an #3x asset covering the entire screen should be 2208x1242 (That is, this resolution is already 3x. The "real" resolution is 736x414). This is the largest resolution needed and you can then use the same image for #2x and #1x assets using the method I described.
You will need three versions of the background image(1x,2x,3x).A good practice to have images of the correct size is to make an image of a size that is 3 times the size of your view and then make the 2x and 1x versions by scaling down.
Apple has come up with a new concept called 'Size Classes' to support the different device sizes.To use size classes you will need the latest version of Xcode(Xcode 6). In the interface builder you can set different set of constraints for different size classes. This way it becomes easier to support all screen sizes. To know more about Size classes watch the WWDC 2014 video "Building Adaptive Apps with UIKit".
Which game engine are you using ?
If you are using cocos2d or cocos2dx then you can use background image of 960 * 640 .Below code will scale the images according to the screen size.
CCSize frameSize = pEGLView->getFrameSize();
CCSize designSize = CCSizeMake(480, 320);
vector<string> searchPaths;
CCSize resourceSize;
Utility :: isPad = true;
searchPaths.push_back("hd");
resourceSize = CCSizeMake(960, 640);
CCEGLView::sharedOpenGLView()->setDesignResolutionSize(designSize.width , designSize.height, kResolutionExactFit);
pDirector->setContentScaleFactor(resourceSize.width/designSize.width);
These are the different resolutions you will need for your background image.
iPhone 4/4S - 640 * 960
iPhone 5/5S - 640 * 1136
iPhone 6 - 750 x 1334 for portrait 1334 x 750 for landscape
iPhone 6 Plus - 1242 x 2208 for portrait 2208 x 1242 for landscape