Advertise Mobile SDKs Books Events Forum News Social Networking Support Us
Follow @iphonedevsdk on Twitter

Interface 2, Advanced iOS
Mockup & Code Gen
($9.99)

Make your own iPhone apps
and run them live!
(free)

Pic Frame Dynamo: Photo Editing
($0.99)

Abiliator
($1.99)

Want your application or service advertised on iPhone Dev SDK?

Go Back   iPhone Dev SDK Forum > iPhone SDK Development Forums > iPhone SDK Development

Reply
 
LinkBack Thread Tools Display Modes
Old 03-25-2011, 02:14 PM   #1 (permalink)
Registered Member
 
scotopia's Avatar
 
Join Date: Oct 2008
Posts: 2,070
scotopia is on a distinguished road
Default Simplest way to handle graphics for iPhone Retina / Not Retina and iPad

Hello All,

I'm working on a universal app right now and I want to have the fewest assets in my bundle as possible. For a simplified example lets assume I have a single asset in my bundle that is 512x512. When the app is running on the iPad I want it displayed as 512x512 at normal resolution (iPad doesn't have retina yet), when the app is running on the iPhone 4 I want it displayed as 512x512 retina resolution (so equivalent to a 256x256 area on a non-retina iPhone), and when the app is running on earlier iPhones I want it displayed as 256x256 regular resolution.

Do I have to make duplicate versions of my asset involving some shenanigans with @2x, or can I simply have that one asset in my bundle and detect with code whether it is Ipad/iPhoneRetina/iPhoneNonRetina and just size it accordingly by setting appropriate bounds on the UIImageView or OpenGL drawing area and such?

Thanks in advance.

Last edited by scotopia; 03-25-2011 at 02:17 PM.
scotopia is offline   Reply With Quote
Old 03-25-2011, 03:58 PM   #2 (permalink)
Reading the Documentation
 
baja_yu's Avatar
 
Join Date: Sep 2010
Location: 45.255019,19.844908
Posts: 5,414
baja_yu has a spectacular aura about
Default

The coordinate system is in points, not pixels. So keep that in mind. On devices with retina display, the scale is 2.0 so 1 point equals two pixels. For the sake of simplicity, lets say you want to show an image that takes the full screen, 320x480 points (status bar removed). For non retina devices you would include an image, call it Photo.png with the size of 320x480, and one called Photo@2x.png with the size of 640x960. Retina devices, with 2.0 scale will know to automatically load the file with @2x suffix. On all devices the UIImage will report the size as 320x480, because it's in points, but the one on retina device will have a scale of 2.0 and others 1.0.

If you don't include @2x images, iOS will load the regular images and scale them to fit, but it wont look as good.

EDIT: See this for some more details: http://developer.apple.com/library/i...esScreens.html
baja_yu is offline   Reply With Quote
Old 03-25-2011, 05:56 PM   #3 (permalink)
Registered Member
 
scotopia's Avatar
 
Join Date: Oct 2008
Posts: 2,070
scotopia is on a distinguished road
Default

Hi Baja,

Thanks for responding. I am aware of the method you suggest; this is exactly what I want to avoid having to do (because in actually I have many large assets and including both regular versions and @2x puts me over a file size threshold that I do not with to go over). Hence I am trying to find a a way to only include the larger versions of the files and have them shrunken down when on appropriate devices (thus instead of needing the Regular Size AND @2x assets in my bundle would only need the larger sized assets).

What I REALLY want to do is only incorporate the largest version of my assets in my bundle (so in the future that would be say 1024x1024 versions for iPad Retina (of the future) ). Then when the app is run for the very first time (can keep track of this with an NSDefault), run some code that goes through the images in the bundle and saves them down to the size appropriate for the device. So, for example my future universal app comes bundled with all my assets as 1024; but on first run it detects that the device is iPhone Retina so it goes through and resaves all the files as 512 (just on that first run) to be used by the app forever more (so the RAM usage is appropriate).

This would mean you only ever have to include one set of assets in your bundle (the largest). Of course it might take a few extra seconds when that app is first loaded to do the bulk resize, but I think its a streamlined approach compared to 3 (or in the future 4) differently sized copies of all your assets in your bundle.

Last edited by scotopia; 03-25-2011 at 06:07 PM.
scotopia is offline   Reply With Quote
Old 04-06-2011, 03:19 PM   #4 (permalink)
Registered Member
 
scotopia's Avatar
 
Join Date: Oct 2008
Posts: 2,070
scotopia is on a distinguished road
Default

Also I am using the images as OpenGL textures (so not using UIImage imageNamed which autograbs @2x images)
scotopia is offline   Reply With Quote
Old 04-06-2011, 05:09 PM   #5 (permalink)
Registered Member
 
Join Date: Oct 2010
Posts: 25
lub997 is on a distinguished road
Default

I haven't converted my app to support Retina or iPad yet, but I am planning to soon, and have been thinking it over for a long time. I have many of the same concerns about it as you, and have thought of the following ideas to deal with it. I haven't tried them yet, though.

You said you wanted the following for your sizes:

iPad (non-Retina): 512 x 512
iPhone (Retina): 512 x 512
iPhone (non-Retina): 256 x 256

While you have 3 screen resolutions to accommodate in this scenario, you only have 2 desired image resolutions as far as what you have mentioned. Considering that, I do see 2 possibilities which might allow you to save space.

Possibility 1: Regardless of the device's screen resolution, your desired image resolution for the iPad and the iPhone Retina are both 512 x 512 as far as you have mentioned. That means you could potentially use the same image file for both the iPhone Retina and the iPad, saving space. I don't know if it will work, but you might try naming the file whatevernameyouwant@2x.png so that the Retina device will recognize it as the proper file to use and then simply use the @2x.png file over again for your iPad code rather than having a separate but identical file without @2x in the filename. You would still have to have a separate file for the 256 x 256 pixel image for the non-Retina iPhone / iPod though. So, in this scenario, you can have 2 files instead of 3, but cannot get it down to only 1 file for each image.

Possibility 2: Do exactly the same as above, but instead of having a separate 256 x 256 pixel file for the non-Retina iPhone, simply use the same 512 x 512 file with the @2x.png filename that you are already sharing between the Retina iPhone and the iPad. If you tell your code specifically to use that filename with the @2x.png code for a non-Retina device, it may allow you to, since you are specifically telling it to. This may allow you to have only 1 file, rather than 2 or 3. The downside of this method is that even if it does work, and I haven't tried it, so I can't guarantee you that it will, the non-Retina iPhone / iPod will automatically scale down the 512 x 512 image to fit within the point-based frame that you have allocated for it, and the scaling will almost certainly make the image grainy looking. If you want to use this method, but XCode turns out not to allow you to use the @2x.png filename on the iPad or the non-Retina iPhone, you could also try having only the 1 512 x 512 file and giving it a normal non-@2x.png filename, and it would still do the same thing anyway, because it is already the larger resolution no matter what you name it, so you would still only have the downside of it being scaled down on the non-Retina iPhone.

If neither of those ideas work for you, you might also consider using something like the GNU Image Manipulation Project (free) or Adobe Photoshop ($$$) to scale down the quality of your photos in .jpeg format, for example, to a quality that has a smaller file size but still a high level of quality when you look at it, and then convert it back to .png or whatever file format you prefer to use. I use the GNU Image Manipulation Project, and have had wonderful results with it. You can download it for free online for any major operating system. Some people prefer Photoshop though. It's all just a matter of preference and what you're used to.

I am not sure how any of these ideas would work with OpenGL, but maybe you can modify one of them to work with it.
lub997 is offline   Reply With Quote
Old 04-06-2011, 06:19 PM   #6 (permalink)
Cocoa Junkie
 
Duncan C's Avatar
 
Join Date: Dec 2008
Location: Northern Virginia
Posts: 6,003
Duncan C has a spectacular aura about
Default

Quote:
Originally Posted by scotopia View Post
Also I am using the images as OpenGL textures (so not using UIImage imageNamed which autograbs @2x images)

If you're using the images as OpenGL textures and don't ever load them into UIImageViews, just save the larger textures and scale them as needed for the target device.

I haven't used OpenGL on iOS, so I don't know if it's supported in OpenGL ES, but at least on the desktop, mip-mapping makes handling large textures gracefully quite easy. You can have OpenGL generate smaller versions of your textures for rendering at different sizes. It only takes a couple of calls to set it up, and uses less memory that you would think.
__________________
Regards,

Duncan C
WareTo

Check out our apps in the Apple App store


Check out this password generator app that shows various techniques including using a data container singleton object to share data between objects in your project.

See this tutorial on using UIView animations and layer animations:

See this thread on generating random, non-repeating text

Check out a very cool Macintosh Kaleidoscopes app called ScopeWorks that we released to the Mac App store.
Duncan C is offline   Reply With Quote
Old 04-07-2011, 09:55 AM   #7 (permalink)
Registered Member
 
scotopia's Avatar
 
Join Date: Oct 2008
Posts: 2,070
scotopia is on a distinguished road
Default

Quote:
Originally Posted by Duncan C View Post
If you're using the images as OpenGL textures and don't ever load them into UIImageViews, just save the larger textures and scale them as needed for the target device.
Hey Duncan. Actually I'm kind of using a combination: most of my assets are displayed via openGL, but some buttons and core graphics type things are overlayed at points. So i'm just looking for kind of a nice universal way to handle all my assets. To me the whole @2x thing seems unnecessary. So my gameplan is basically this so far:

1) only include the largest version of all assets needed in my bundle (no @2x copies or anything)
2) at application startup detect what type of device it is by using
code like:

Code:
CGSize PhysicalPixelSizeOfScreen(UIScreen *s) {
    CGSize result = s.bounds.size;

    if ([s respondsToSelector: @selector(scale)]) {
        CGFloat scale = s.scale;
        result = CGSizeMake(result.width * scale, result.height * scale);
    }

    return result;
}
and set a variable based on this.

3) based on above variable have branching cases throughout code to display things properly for each device


Does this sound like a proper approach? I have a follow up question, but first let me see if I'm on target with my thinking
scotopia is offline   Reply With Quote
Old 04-08-2011, 10:14 PM   #9 (permalink)
Super Moderator
 
Join Date: Oct 2009
Location: San Diego, CA
Posts: 1,586
JasonR is on a distinguished road
Default

I find that most of the UIKit classes that take images will automatically scale down an image to fit into a view or control. So I just put the higher resolution image in and forget about it. And CGContextDrawImage also seems to scale well if you need to draw an image yourself with Quartz.

Now, others have claimed their images don't scale well, so test it with a few of the images you are using before you get too far into it. You might find a few images are worth making @2x version of.
__________________
My development blog: http://jrinn.com
JasonR is offline   Reply With Quote
Old 04-08-2011, 10:30 PM   #10 (permalink)
Registered Member
 
scotopia's Avatar
 
Join Date: Oct 2008
Posts: 2,070
scotopia is on a distinguished road
Default

Yeah; I think I just need to play around some more. To that point; do you know if there is a way to set the simulator to an earlier generation iPhone (pre retina)? My only options seem to be iPad or iPhone 4; do I have to set my target back to an earlier setting or something (my app is new so it only has the newest options defaultly available); thanks.
scotopia is offline   Reply With Quote
Old 04-08-2011, 10:38 PM   #11 (permalink)
Super Moderator
 
Join Date: Oct 2009
Location: San Diego, CA
Posts: 1,586
JasonR is on a distinguished road
Default

I'm using the latest XCode4, and the iPhone simulator show iPhone and iPhone(Retina) as 2 choices under Hardware->Device.
__________________
My development blog: http://jrinn.com
JasonR is offline   Reply With Quote
Old 04-08-2011, 11:15 PM   #12 (permalink)
Registered Member
 
scotopia's Avatar
 
Join Date: Oct 2008
Posts: 2,070
scotopia is on a distinguished road
Default

Quote:
Originally Posted by JasonR View Post
I'm using the latest XCode4, and the iPhone simulator show iPhone and iPhone(Retina) as 2 choices under Hardware->Device.
Thanks; I see that I can change that in the Simulator and then just open the app; but is there away to get that right from xCode (so I can build it and see the debugger output for the different versions?). For instance my only build options are iPhone 4.3 and iPad 4.3 (so I can see debugger output). Now, once the simulator is opened I can change the device to to pre-retina iPhone and open the app; but no debugger output.

I also just realized that a UIView's frame is specified in points (not pixels); so for instance if my base asset was 512 x 512 and it was in a UIImage called displayImage:

displayImage.frame=CGRectMake(0.0, 0.0, 256.0, 256.0);

would cover a 512x512 pixel space on my retina iPhone (thus my image will be at the perfect resolution)

and it would cover 256x256 pixels on a pre retina iPhone (thus my asset will be scaled down 50% which should be fine).
scotopia is offline   Reply With Quote
Old 04-09-2011, 02:05 AM   #13 (permalink)
Super Moderator
 
Join Date: Oct 2009
Location: San Diego, CA
Posts: 1,586
JasonR is on a distinguished road
Default

It's annoying, you have to change to iPhone(Retina) first in the Simulator, then go back to XCode to debug again. I get debugger output either way as long as I pick the device in the simulator first.
__________________
My development blog: http://jrinn.com
JasonR is offline   Reply With Quote
Old 04-12-2011, 01:28 PM   #14 (permalink)
Registered Member
 
scotopia's Avatar
 
Join Date: Oct 2008
Posts: 2,070
scotopia is on a distinguished road
Default

Quote:
Originally Posted by JasonR View Post
It's annoying, you have to change to iPhone(Retina) first in the Simulator, then go back to XCode to debug again. I get debugger output either way as long as I pick the device in the simulator first.
I see; indeed annoying!
scotopia is offline   Reply With Quote
Reply

Bookmarks

Tags
image, retina

Thread Tools
Display Modes

Posting Rules
You may not post new threads
You may not post replies
You may not post attachments
You may not edit your posts

BB code is On
Smilies are On
[IMG] code is On
HTML code is Off
Trackbacks are On
Pingbacks are On
Refbacks are On



» Advertisements
» Online Users: 372
12 members and 360 guests
condor304, dansparrow, Domele, dre, dreamdash3, ilmman, LezB44, michelle, Sami Gh, shagor012, thephotographer, tinamm64
Most users ever online was 1,387, 04-10-2012 at 04:21 AM.
» Stats
Members: 175,663
Threads: 94,119
Posts: 402,896
Top Poster: BrianSlick (7,990)
Welcome to our newest member, LezB44
Powered by vBadvanced CMPS v3.1.0

All times are GMT -5. The time now is 01:35 AM.
Powered by vBulletin® Version 3.8.0
Copyright ©2000 - 2012, Jelsoft Enterprises Ltd.
Search Engine Friendly URLs by vBSEO 3.3.0