Not including non-retina display images in an iPhone project - iphone

I have an iPhone Xcode project that currently only contains images for retina display (twice the size as normal and with a #2x.png suffix). When I run the app on the iPhone Simulator (non retina) the images are still being displayed. Does this mean I don't need to worry about including two sets of images: retina and non-retina?
This all seems a bit odd. I would assume that no images would appear on a non retina device if there are no non-#2x files included.
Note: I have not tested my app on a non retina device. Just the simulator.

I'm pretty sure that iOS will just use the #2x and scale it down if you don't have a non-retina graphic. Although that's sub-optimal since you're letting iOS do the scaling at runtime which will be slower than including the non-retina graphic and also iOS might not do as good a job as scaling as your graphics editor of choice.

Even if it works, it's not good practice, and if you have a media heavy app definitely it would impact performance and battery life and memory foot print and ....
By the way, is it just that you don't have the 1x graphics available to you or you are concerned about your apps (download size) or ...

If you are assigning the images in Interface Builder, and you set the image property on a UIImageView to image#2x.png, for example, iOS will not know that it's a high resolution "2x" image. In fact, on a retina display, iOS will look for an image named image#2x#2x.png. Since it won't find it, it will set the scale factor of the image to 1.0.
The contentMode property (just "mode" in XCode) will decide if any scaling of the image occurs to fit the constraints of the UIImageView. You may wish to set the mode to "Aspect Fit" to get the high resolution image to scale as needed for both retina and non-retina displays. In general, the image will display as seen in Interface Builder.
If you are using UIImage's imageNamed or similar function to load the image, and just specify image (where "image.png" doesn't exist, but "image#2x.png" does), then iOS will actually find the image on a non-retina display, though the scale factor will be 1.0. As previously, you'll need to scale it to fit your view. The image will work normally on a retina device, and the scale factor will be set to 2.0, since iOS looks for a "2x" image first, and it doesn't matter if the other file exists or not.
This is from Apple's documentation on imageNamed:
On a device running iOS 4 or later, the behavior is identical if the
device’s screen has a scale of 1.0. If the screen has a scale of 2.0,
this method first searches for an image file with the same filename
with an #2x suffix appended to it. For example, if the file’s name is
button, it first searches for button#2x. If it finds a 2x, it loads
that image and sets the scale property of the returned UIImage object
to 2.0. Otherwise, it loads the unmodified filename and sets the scale
property to 1.0. See iOS App Programming Guide for more information on
supporting images with different scale factors.
If at all possible, you really should include both retina and non-retina images. Using higher-resolution images than necessary negatively affects memory and performance.

Related

Reducing iOS app size - Are <imagename>#2x.png images redundant?

I am trying to reduce the size (30+ MB) of my binary submission, and I sense that images acquire a sizable (>26 MB) part.
I also observed that if I remove retina images (#2x.png), iOS gracefully replaces them with 4-inch retina (-568h#2x.png) versions.
Are the retina images really redundant if I supply -568h#2x.png versions?
P.S.
Not that one image makes much of a difference, but if the answer is a Yes, does this also apply for default.png?
#2x images are for retina devices. They look much crisper and clean on retina devices (e.g. iPad3, iPhone 5) as compared to their non-retina counterpart images. Here are few suggestions to reduce size of your binary.
1) For background images check if they are really needed. If they are simple solid color images you can simply set the backgroundColor of the UIView.
2) Whenever possible use 9 patch (also called 9 scale) images for button or view backgrounds. They are generally 1 px wide images and you can use below method of UIImage to use them
- (UIImage *)resizableImageWithCapInsets:(UIEdgeInsets)capInsets resizingMode:(UIImageResizingMode)resizingMode
In general image#2x can be used as a stand in for image, but not the other way around (because they wouldn't look good). The side effect of doing this is that more memory will be used and on non-retina devices that could cause a problem. If you aren't supporting non-retina devices then you don't need any images.
Generally speaking you shouldn't have many image-568h#2x images other than the Default and other background images. Most of your content images will be the same size no matter what the screen size is. You do not need differently named images for a button of the same size on multiple different screen sizes.

XCode iOS simulator - application is pixelated

I'm a beginner with XCode and I've encountered an issue. When I build my application, it looks fine in the standard iPhone simulator, but when I change the hardware to a retina device, the UI elements of my application become pixelated. How can I fix this?
You're seeing that because the retina screen is stretching the image you're supplying across more points on the screen. You can supply hi-res images in your bundle by appending #2x to the filename
http://developer.apple.com/library/ios/#documentation/uikit/reference/UIImage_Class/Reference/Reference.html: "If you load an image from a file whose name includes the #2x modifier, the scale is set to 2.0. You can also specify an explicit scale factor when initializing an image from a Core Graphics image. All other images are assumed to have a scale factor of 1.0. "
Here's a guide to supporting high-resolution screens.
As #RobotWoods mentioned, all images in your app need to have #2x versions.
If you're using OpenGL ES, custom code that creates images, or core animation, you need to make sure your code accounts for the display's scale.
If you're using only standard UIKit elements like UIButton, UILabel, UITableView, etc. then all you need to do is provide the #2x images.
If that doesn't help, please post screenshots and relevant code of what looks blurry.

Cocos2d/Cocos2d-x Retina Issues

I have a multiplatform iOS/Android game that I programmed in Cocos2d-x. I have only one set of images to use (I'm only after high res devices) that get scaled according to the device's resolution. For example all images are for the iPad but if you are using a Galaxy S then the image locations and scaling are affected by GalaxyS_screenWidth/iPadscreenWidth.
This works fine for all Android devices and on iPad, iPad2 and old iPhones, but with Retina iPhone there is a problem. On the iPhone 4 all my images look extremely pixelated, a result from the images being scaled to iPhone non-retina resolution then scaled back up to fill the screen.
I tried enabling Retina Mode and the images are half of their intended size (maybe due to the usage of get winsize() which uses points) and scaling manually causes other sorts of problems. I tried playing with a lot of options and attributes but to no avail, so what should I do now?
EDIT:
This is not only a graphics issue, as text gets automatically scaled down then up and appears pixelated.
EDIT 2:
Fonts are bitmaps so my bad. But I don't want to use retina as all images are already retina by default. All of my images are set up for the iPad so for iPhone 4 I just scale them down a bit. This works with Android phones.
For example I have an image, depending on screen resolution obtained through getwinsize():
If current resolution width is 1024 then image stays the same.
If current resolution width is 900 then image gets scaled by 900/1024, no problem.
If device is iPhone 4 resolution width is 480, so image gets scaled by 480/1024, then cocos2d-x automatically scales the resulting image by 2 thus the pixelation. I tried using getwinsizeinpixels, I tried multiplying the screen size, I tried many things but nothing worked out of the box unless I am to redo many of my code.
So the question is, how can I just let the damn engine treat the iPhone 4 as an Android phone with resolution of 960x640?
If you want Retina resolution images to look like Retina resolution images, then those images need to be in Retina resolution (960x480).
If you first scale down the image to 480x320 and then upscale it on the device, it will of course look blurred. You can't magically make the Retina pixels appear from a lower resolution image by scaling it up.
SI couldn't get to the bottom of it so I employed a hack. I enabled Retina Display then I scaled everything x2 through code except for the text. Sounds stupid, but it worked, and pixelation is gone. Thanks everyone who spent time trying to help me.
I tried enabling Retina Mode and the images are half of their intended size
when you enable retina support, cocos2d gets images by appending #"-hd" to their provided filenames. Such images are meant to be double the "visual" size (in iOS terms, pixels vs. points), so that they can be sort of scaled down to make full use of device resolution.
If you have a look at the CCDirectorIOS class, you will find there a couple of methods dealing with this, especially those dealing with the scalingFactor. I don't know what kind of changes you should do to make it work, but if you step into those methods and look at the value of various objects, you might find a way to modify cocos2D default behavior for your specific case.
If this seems to complicated, one thing you could try is changing the CC_RETINA_DISPLAY_FILENAME_SUFFIX so that cocos2d will not look for specially-named files for the retina iPhone, but just use the normal ones.
For example all images are for the iPad but if you are using a Galaxy S then the image locations and scaling are affected by GalaxyS_screenWidth/iPadscreenWidth.
Another thing you might try is not using winSize, but winSizeInPixels, so that when you scale down, you down do it down to the point resolution, but just to the pixel resolution (which is double the point resolution).
Hope this helps.

What size images should I use in order to support the two iphone resolutions?

I have a few questions about screen resolution, that I'm not clear on. These questions assume they my app will be running on iOS 4.0 and up, and on either iPhone 3GS or iPhone 4.
Should the size of the splash image (default.png) be (960x640) or (480x320)?
Should the size of the app icon (Icon.png) be (57x57) or (114x114)?
What about other graphics that I may use in my app, such a graphic that represents a button? Should I always create these images for the higher resolution, and have the app scale them down? In other words, if I want a button image to be displayed on the 3GS that is 200x40 - should I create the image at 400x80, so that iPhone 4 can take advantage of it?
Thanks!
A good guide to this can be found here: http://mobile.tutsplus.com/tutorials/iphone/preparing-your-iphone-app-for-higher-resolutions/
In general you just create 2 sets of images. Your original and then a new one twice as big with #2x in the name. So for image.png at size 32x32 you would have one that is twice the resolution called image#2x.png at size 64x64. In your app just always use the image.png in Interface Builder and when loading in code.
There is no need to detect the device. These images will automatically be picked up by the OS and subbed in as necessary.
Provide both sizes (960x640 & 480x320) for the splash image using the #2x method described above
Provide both icons (57x57 & 114x114) using the #2x method
For our apps we use a combination of the #2x images and just Scaling the large images. (More information on this can be found in the above article) We use the #2x images for bar buttons, icons, etc. But for UIImageViews we often just use the Scaling. There can be a performance hit for doing this, but for most apps I'd say this is negligible. The savings in file size sometimes make scaling the only option.
Related Questions:
Retina/non-retina images in UIImageView
Making an app Retina Display friendly
You need to provide both if you want them to look nice. For example,
Default.png -> (480x320)
Amd
Default#2x.png -> (960x640)

High Resolution iPhone Background

According to Apple's website, the iPhone 4 is 960-by-640-pixel resolution at 326 ppi. I made an image with these specs, however when I put it onto my iPhone as a background for one of my applications, it is way too big and you can only see the upper left corner of the image. How do I make it fit and how do I make a high resolution iPhone 4 background?
You need to give it the name "someImage#2x.png" with the important part being #2x so they can apply the scale correctly.
Realize though that you also need "someImage.png" which is half that size for devices without the retina display.
I always use the "someImage.png" file as the initial image and then the OS will automagically switch to the #2x image during runtime so don't worry about that. Just set it to the standard 320x480 or 480x320 and let the OS do the rest.
Are you using an UIImageView? You should have two versions of your images
image.png - normal 320x480 image for older phones
image#2x.png - for iphone4 with the 640x960 resolution
When you set the file location (be it programically or in Interface Builder) just tell it about the 'image.png'. The iPhone4 will automatically look for the '#2x' version.