Sprite Atlas and #2x images - iphone

When using texture atlas (iPhone5) do I have to include sprite images at both normal and normal#2x sizes (even though I am only targeting retina devices). I thought I could getaway with only adding the #2x versions but sadly when I run the application the sprites come out a lot bigger than they should be (nearly 4x), I only get the right size sprites displayed when I add the normal (#1x) images to the atlas as well.
EDIT:
Starting a new project file in Xcode, if you want an image to fill the whole device display (iPhone5/5S at the maximum resolution) you need to use the #2x extension (in this case there is no "background_003.png" in the Xcode project so just the #2x version is fine)
// SETUP BACKGROUND FRAME IS {320, 568} POINTS
// IMAGE "background_003#2x.png" = 640 x 1136 Pixels
SKSpriteNode *background = [SKSpriteNode spriteNodeWithImageNamed:#"background_003"];
[background setAnchorPoint:CGPointZero];
[background setPosition:CGPointZero];
[self addChild:background];
If you add the correct sized image (640 x 1136) without the #2x Xcode takes the image and scales it incorrectly by the devices 2.0 point size, resulting in an image that is twice as big as the display.
// SETUP BACKGROUND FRAME IS {320, 568} POINTS
// IMAGE "background_001.png" = 640 x 1136 Pixels
SKSpriteNode *background = [SKSpriteNode spriteNodeWithImageNamed:#"background_001"];
[background setAnchorPoint:CGPointZero];
[background setPosition:CGPointZero];
[self addChild:background];
RESULT:
After a little bit of testing this morning I have now realised that my problem was the result of adding sprite frames in an atlas without the #2x postfix and then renaming them to include the missing #2x. It would seem that when using folder.atlas Xcode creates a plist somewhere that references the files, I can't find this and it only seems to get updated when you first add your atlas to your project. After deleting and re-adding the atlas Xcode started correctly displaying the #2x images at the right scale.
The moral of this story is therefore: if you change an atlas or its contents, make a copy, delete it from your Xcode project and re-add it again. Create all your artwork at retina resolution and add the #2x postfix to all your files, you only need none retina files (without the #2x if your targeting a none retina device) Finally when referring to art assets in code don't use the #2x postfix, so even though your monster sprite art is called "Monster_0001#2x.png" you should be referring to it in code as "Monster_0001" Xcode will work out the #2x bit for you behind the scenes, also if your using PNGs (which you should be) it will even add the ".png" for you too.
// THE ART ASSET ON DISK IS CALLED: "Monster_0001#2x.png"
SKSpriteNode *spriteMonster = [SKSpriteNode spriteNodeWithImageNamed:#"Monster_0001"];

If you only support Retina devices just add files without the #2x and you'll be fine.

Related

iOS8 Retina #2x images not scaling like iOS7?

Has the way that Xcode 6.1 (iOS 8.1) changed the way that images are handled. In my previous Sprite Kit game (Xcode 5, iOS 7) I used the following full screen image as a background:
MainBackground_IP5#2x.png // RESOLUTION: 640 x 1136, it fills screen.
Now in Xcode 6.1 I am testing the following code (See below), the image I am using is:
MainBackground_IP6#2x.png // RESOLUTION: 750 x 1334
CODE:
func setupBackdrop() {
println(__FUNCTION__)
let backdropSprite = SKSpriteNode(imageNamed: "MainBackground_IP6")
backdropSprite.anchorPoint = CGPointZero
backdropSprite.position = CGPointZero
self.addChild(backdropSprite)
}
However when I run the application both on the simulator and device I get the following.
NOTE: If I remove the #2x it fits fine, but I can,t understand whats changed, I have not seen this mentioned in any Sprite Kit notes? I even loaded my old iPhone 5 game project and all the #2x backgrounds fit perfectly in that, it must just be iOS 8.
Images should use #2x but the problem was that in the GameScene.sks I had entered the screen resolution in pixels not points (should have been 375 x 667) Also there seems to be a problem with the GameScene.sks on the template, if you add items programatically as I did they quite often don't display. The solution to this seems to be that you have to add at least one node to the GameScene.sks (I just added an empty SKNode)

How to create big image when we have small image in iOS without pixel distortion?

I am working on an app which is fully dependent on images. I have images like 320*480 now I want those same images with 768*1024 dimension. I can get it by UI designer and place in my bundle but my application is for universal app so I needed to include same image for iPhone retina, iPad, iPad retina. If I am using multiple images my IPA size goes increase (ex: if an image with 320*480 having 200KB now if I again adding 768*1024 the size of my IPA will increased to at least 200KB).
Idea: I am placing only 320*480 images and planning to create 768*1024 images programmatically which means only one set of images I am using in my bundle.
Work done: By looking some blogs I found that using below code we can create required image sizes.
- (UIImage *)scale:(UIImage *)image toSize:(CGSize)size
{
UIGraphicsBeginImageContext(size);
[image drawInRect:CGRectMake(0, 0, size.width, size.height)];
UIImage *scaledImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return scaledImage;
}
UIImage *smallImage=[UIImage imageNamed:#"1.png"];
UIImage *bigImage=[self scale:smallImage toSize:CGSizeMake(768, 1024)];
[UIImageJPEGRepresentation(bigImage,2.0) writeToFile:[[self applicationDocumentsDirectory]stringByAppendingPathComponent:#"upload.png"] atomically:YES];
Problem: Above code works cool and getting the expected size of images but only problem is I am getting pixel distortion on the end image.
Question:
Is there any good or efficient solution to get different dimensions with out distortion image from the small image or I need to get all my images from the UI designer. If we have normal Image can we create same image for retina display?
Is there a better solution?
It is impossible to create a larger image from a smaller image without distortion or pixelation. There is no way to magically fill in the additional detail.
The real world doesn't work like TV or movies where people zoom in on images and magically get a lot of detail. :)
If you feel that your app is too big when you include 5 sets of images for:
iPhone 3.5" non-retina
iPhone 3.5" retina
iPhone 4" retina
iPad non-retina
iPad retina
then you have a few options:
Make two apps. One for iPhones and iPod touches, and one for iPads.
Ship your app with only a small subset of images. Then when the app is run the 1st time, the app can download only the images required for the current device.
Only include the largest images. As the app needs each image, it can create a properly sized version of the image and use that. Each conversion would only need to be done once per image. Downsizing an image gives much better results than trying to upscale.
You can resize image programmatically but they will not look good. I wouldn't worry that much about bundle size. Just put native-resolution image for all devices and forget about resizing.
If you want, you can crop and scale down from the big images, but if you are scaling up, there will be quality loss because the file does not contain enough information for all of those pixels. I would suggest either:
1) The easiest method is to make a bunch of different versions of the image. (see rmaddy's answer).
2) If you really don't want multiple images, take the largest one and scale downwards. Since they have different aspect ratios, simply scaling will cause some distortion; you will need to crop as well.
Either way, you will need to open up your image editor and make a larger image.

Retina graphics

I'm using an image that fills the screen (like a background) to my app. The image is already in retina dimensions, but I scaled it to fit the simulator screen. Because it's already in retina dimensions, do I still need to add a copy of it with the #2x extension?
It's better to use separate images, normal & normal#2x. if you only use single image, small images will be distorted while bigger image will look squeezed.
don't forget the iphone 5 for background images for example.
3 images are required : Background-568h.png Background.png Background#2x.png
if ([UIScreen mainScreen].bounds.size.height > 480.0f) {
// for the iPhone 5
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"Background-568h.png"]];
} else {
// for iphone 3.5 inch retina /non retina.
self.view.backgroundColor = [UIColor colorWithPatternImage:[UIImage imageNamed:#"Background.png"]];
}
the naming notation is required for compiler to detect your retina images.if you write image.png the compiler looks for image#2x.png and then image.png and if it can not find it(for retina displays).
So name all your images xxx#2x.png and provide also xxx.png for non retina devices.
On the other hand i would use exact image sizes for non-strechable images in you app.Resizing means extra time and naturally extra computation.On the other hand fractional image resolutions ends up with blurry images.
For iphone 5 images you should for instance include Iphone5BackgorundIamge#2x.png but call Iphone5BackgorundIamge.png in your code.
Iphone dont have to do with image dimension but it uses image name for checking whether it is to be used as ratina or normal image.You have to keep a normal size image with it's name like "image1.png" for normal display and ratina size image as "image1#2x.png" for ratina display.If your used image is already of ratina display then keep it with #2x format and put one half size image with normal name.

How to scale images (not resources) to iPhone Retina display correctly in a view?

I have a UIImage, from either device's camera or downloaded from a URL. Say resolution is 800x600.
I want to display a scaled image in a UIImageView which is 200x150, and I have a proper image scaling code.
So, I just scale the UIImage to the UIImageView's frame.size (again, 200x150). On a non-retina display it looks OK, but on a retina display it looks bad, like a smaller picture was scaled up, because the actual frame in pixels is 400x300.
The question is - should I, manually multiply the frame.size.width/height by 2 when it's a retina display when I resize, so it'll be resized to 400x300, or is there a built in feature for that?
Since the UIImage is not a resource on the device, I don't have the #2x option.
Keep the frame size of the image view at 200x150 in all cases.
In case of non-retina display scale the image to 200x150. On retina display devices scale it to 400x300. Set the contentMode of the UIImageView to UIViewContentModeScaleAspectFit.
When you get the image in say 800x600, can't you make a UIImage that is scaled to 400x300 and save it temporarily with the #2x extension, maybe to the Documents folder or tmp folder, and then save another UIImage scaled to 200x150 and save it without the #2x in the same directory.

Upgrading a cocos2d iPhone game to work at iPhone4 resolution using #2x

I am trying to add art to my game for the iPhone4 resolution. The images i am using are twice the original and i have added the #2x suffix to the image names.
When i load in a sprite like this:
[CCSprite spritewithFile:#"example.png"];
where example.png is the original image and example#2x.png is the scaled up version. When running on the original iPhone it loads the low res image and when running on the iPHone4 it loads the high res image, but it doubles the size of the image. So the high res image appears the same on the iPhone4 as on the original iPhone. Each pixel on the image takes up 4 pixels on the screen.
Any idea why this might be happening? Is there something I am supposed to do to tell the app not to double the size of the art?
Are you using the latest version of cocos2d?
The entire cocos2d API was converted
to Points. Previous versions were
using Pixels.
If your using v0.99.4:
cocos2d v0.99.4 has RetinaDisplay
support, however it required you to
use two different sets of positions
depending on the device , since the
API was in Pixels. (more)
If your using >= v0.99.5-rc0
But in v0.99.5-rc0 (and newer) the only thing that you have to do is[...] (more)
Have you read the "Retina Display in cocos2d" section of the cocos2d for iPhone wiki? (It pretty much tells you all you need to know.)