@1x vs @2x vs @3x

I understand how (or correct me if I’m wrong) Retina works in regards to the “I” devices.
You supply 3 versions of an icon/graphic, where one is (example) 32x32 which would be used for iPad2 (non-retina),
and 64x64 (for Iphone4/5, and Ipad Retina), and 96x96 for new iPhone6/6+, these would be named (example)
image.png, image@2x.png and image@3x.png.

You code would reference only “image.png” and iOS will replace it if necessary with the @2x or @3x version based on device.

NOW… all that being said (assuming I stated it correctly).

What if you DON’T supply all 3 versions?

  • If you supply only 32x32 (image.png), what does Retina and iPhone6 do?, do they upscale the supplied image? or show the wrong “size”
  • Same if you only supply the @2x version, what does iPad2 do? what does iPhone6 do?
  • lastly, what if you supply a single LARGER image (say 192x192), and use drawpicture to resize it? Does the developer have to resize based on device? or would the resize convert Points to Pixels and create an image the correct number of pixels based on device?

I have an app idea, that if I had to create all 3 versions of each graphic, would 3 x 180 images (540 total), not only is that a TON of images to manage (let alone create), its a huge impact on bundle size. So I’m actually hoping that bullet #3 results in a “good” result, and I only have to manage ONE version of each graphic, and can have the app downscale to the device when the app initializes.

Am I way off base here? Ideas? comments?

It will upscale or downscale on the basis of what image you give and it needs.
The downscale is better than upscale (obviously)
But if you make the images for all the sizes then you can understand whether if better to not have smaller details in the images (for the lower sizes) that will not give the desired effect but instead appear as “noise”.
Using only the automatic downscale then you save space but you can have images with artifacts.

And don’t forget that this “scale” operation is not without a power and time cost.

So you are saying…if I supply ONE image (larger than required for @3x) and reference it without the “@” designator .

I realize that there is a cost, nice thing is, that cost can be consumed once at app startup. The images can be loaded into an array or dictionary once they have be scaled for the device.

Downscaling might produce some “blur” at smaller sizes, but I’m kind of hoping that the pixel/point will minimize how the eye percieves it

Try
Generally depends on the image contents and sometime the results are worst then you expect, sometimes better

Apple does caution about downscaling artifacts that can occur doing this
They give guidelines on this sort of thing to try & nudge you in the right direction and suggest providing all 3 pngs (which will be quite small at any rate)

For tasks like this, I can only recommend to have a look at Affinity Designer. Create your graphics as vector and export them to all 3 PNG sizes with one click. This won’t reduce the bundle size, although for icons it can’t be that much, but you don’t have to create differently sized images.

EDIT: I did not find references to this, but it seems to me you can also attach an ~iPad extension to the filename and this way restrict the use of the image to iPad only. Probably there will be an ~iPhone extension too – if I am right. Do you know any references for this? (I tried to run an iOS app with an image with an ~iPad extension and it did not appear on an iPhone view until I removed the tag.) If this is a feature indeed, it saves a lot of manual file handling again if you need different images for the different devices.

Keep in mind that these devices don’t have as much memory as we do on the desktop. Preloading all of the images may actually hurt you and the user in the long run.

+1 for Affinity Designer.

I’ve been using it at work creating iPhone apps, and it has saved me a lot of work. I create the image at the desired size for the standard image, and then Affinity can automatically upscale it for @2x and @3x. This works fine as long as the images are vector graphics… obviously if there are any bitmap elements in the image, then the upscaling isn’t as good.

The idea is to only preload (and resize from a larger image), the correct version for the device. I see a trade off here.

  1. Having @1x, @2x, @3x versions, increases the bundle size, and as you mentioned, limited memory, and on the “i” devices there is no distinction between “application running” and “storage” memory, unlike the desktop where you have “RAM” and “HardDisk”, this penalizes the device owner by having to store images that cannot be used by that device.

  2. So I’m leaning toward resizing, the amount of “memory” accounts for only “two” versions, the large version in “storage”, and the working/resized version in “application runtime”, this takes more time at startup (like a whole second or two), minimizes the number of images to maintain.

And so far all the tests I have done, using a base image of 150x215pixels… and resizing it to from as small as 43x62 [iphone4s] up to 93x134 for iPad the results look quite good (in the simulator, and on my real iPad2) (sizes in POINTS of course, with the iPad2 being only @1x)

One problem with that is that UIImages will be purged in low memory situations and it will then take longer (and more memory) to properly resize them when they are reloaded instead of reloading them directly from disk at the correct size.

Understood… but here is my problem.
I have 175 base images… the content of these do not change
Consider the fact that they are PLAYING CARDS (3 different decks + Card Backs + misc images)
for each “I” device the optimum size is different (to show the required number of cards at one time)
so with 6 different resolutions (4s, 5s, 6, 6+, IP2, IP-retina) that results in 1,050+ png files

From what I can find, it seems MOST newer devices have an “application memory budget” of around 640Meg before it will crash
according to this utility https://github.com/Split82/iOSMemoryBudgetTest
with the exception of the iPad2 which is much lower… According to this, 212Meg is memory warning point (and this is with over 1/2 other apps running in the background)… So far my app has not gone past 16meg

Seems the Simulator doesn’t simulate device memory, as this utility said a 6+ had 8GIG of application budget :), but on a real device it seems to be accurate (according to forum posts I found)

[quote=187948:@Dave S]The idea is to only preload (and resize from a larger image), the correct version for the device. I see a trade off here.

  1. Having @1x, @2x, @3x versions, increases the bundle size, and as you mentioned, limited memory, and on the “i” devices there is no distinction between “application running” and “storage” memory
    [/quote]
    Not true
    There is a limited amount of memory available to RUN apps & iOS but the iDevice may have 8 16 32 etc Gb of storage
    It does however use Virtual memory like desktop
    Also Apple recommends against this as well
    https://developer.apple.com/library/ios/documentation/iPhone/Conceptual/iPhoneOSProgrammingGuide/PerformanceTips/PerformanceTips.html#//apple_ref/doc/uid/TP40007072-CH7-SW8
    Load resources lazily.
    You should never load a resource file until it is actually needed. Prefetching resource files may seem like a way to save time, but this practice actually slows down your app right away. In addition, if you end up not using the resource, loading it wastes memory for no good purpose.

Could you maybe use a UIImageAsset? I’m not familiar with it but it looks like it might help.
https://developer.apple.com/library/prerelease/ios/documentation/UIKit/Reference/UIImageAsset_Ref/index.html

What about resizing the images on first run and saving them off to your application documents folder? No need to resize them every time the app runs. Then check for their existence in this folder when you need to load an image.