iOS SDK retine images vs using bigger images for smaller placeholders - ios

Is it the same if I use a big image i.e. a 40x40 image in a 20x20 place holder or a #2x image for retina?
I mean, I have two alternatives:
- use a 20x20 image.png and 40x40 image#2x.png
- use a 40x40 image.png
Is it the same?
Thanks.

Using only retina images and leaving the down-scaling on non-retina devices up to the system is possible but not recommendable in all cases.
It really depends on the contents of your graphics. If, for example you are using vector based graphics as your source (sharp lines etc.), then offering only the retina images will result into washed, blurry images on non-retina displays.
Again, it is possible and entirely fine if your content still looks good enough.

Related

Xcode #2x image suffix not showing as Retina in iOS

I am having difficulties with retina images.
The screenshot below shows the UICollectionView with a UIImageView contained within each UICollectionViewCell.
Within the app I have a large image 512x512 pixels called travel.png.
The green circle shows what is displayed on the app when I name this file: travel.png. The blue circle shows what I see when I update the image name to be travel#2x.png (i.e. retina naming).
I was hoping due to the large size of the image (512x512) that simply adding the #2x suffix would be enough to convert it to twice the definition (i.e. retina) but as you can see from the two screenshots, both version images show as non-retina.
How can I update the image so that it will display in retina?
travel.png:
travel#2x.png:
* Updated *
Following request in comments below:
I load this image by calling the following function:
// Note - when this method is called: contentMode is set to .scaleAspectFit & imageName is "travel"
public func setImageName(imageName: String, contentMode: ContentMode) {
self.contentMode = contentMode
if let image = UIImage(named: imageName) {
self.image = image
}
}
Here is how the image appears in Xcode before the app renders it (as you can see it is high enough definition):
The reason why you see the low quality image is anti-aliasing. When you provide images bigger then an actual frame of UIImageView (scaleAspectFit mode) the system will automatically downscale them. During scaling some anti-aliasing effects can be added at curve shapes. To avoid the effect you should provide the exact image size you want to display on the screen.
To detect if UIImageView autoscale the image you can switch on Debug->Color Misaligned Images at Simulator menu:
Now all scaled images will highlight at simulator with yellow color. Each highlighted image may have anti-aliasing artifacts and affect CPU usage for scaling algorithms:
To resolve the issue you should use exact sizes. So the system will use them directly without any additional calculations. For example, if your button have 80x80px size you should add three images to assert catalog with following sizes and dpi: 80x80px (72 dpi), 160x160px (144 dpi) and 240x240px (216 dpi):
Now the image will be drawn at the screen without downscaling with much better visual quality:
If your intention is to have just one image for all the sizes, I would suggest it having under Assets.xcassets. It is easy to create the folder structures and manage media assets here.
Steps
On clicking + icon, you will displayed a list of actions. Choose to create a New folder.
Choosing the new folder that is created, click on the + icon again and click on New Image Set.
Choose the imageset. And choose the attributes inspector.
Select Single Scale, under Scales.
Drag and drop the image.
Rename the image name and folder names as you wish.
Now you can use this image using the image name for all the screen sizes.
TL;DR;
Change the view layer's minificationFilter to .trilinear
imageView.layer.minificationFilter = .trilinear
as illustrated by the device screenshot below
As Anton's answer correctly pointed out, the aliasing effet you observe is caused by the large difference in dimensions between the source image and the image view it's displayed in. Adding the #2x suffix won't change anything if you do not change the dimensions of the source image itself.
That said there is an easy way to improve the situation without resizing the original image: CALayer offers some control over the method used by the graphics back-end to resize images : minificationFilter and magnificationFilter. The first one is relevant in your case since the image size is being reduced. The default value is CALayerContentsFilter.linear, just switch to .trilinear for a much better result (more info on those wikipedia pages). This will require more GPU power (thus battery), especially if you apply it on many images.
You should really consider resizing the images before displaying them, either statically or at run-time (and maybe cache the resized versions). In addition to the bad visual quality, using such large images in quantities in your UI will decrease performance and waste lots of memory, leading to potentially other issues.
I have fixed, #DarshanKunjadiya issue.
Make sure (if you are already using assets):
Make sure images are not un-assigned
Now use images in storyboard or code without extensions. (e.g. "image" NOT "image.png")
If you are not using images from assets, move them to assets.
Demo Projects
Hope it helps.
Let me know of your feedback.
I think images without the #2x and #3x are rendered for devices with low resolutions (like the iphone 4 an 3G).
The solution I think is to always use the .xcassets file or to add the #2x or #3X in the names of your images.
In iOS, content is placed on the screen based on the iOS coordinate system. for displaying an image on a standard resolution system having 1:1 pixel density we should supply image at #1x resolution. for higher resolution displays the pixel density will be a scale factor of 2.0, 3.0 which refers in the iOS system as #2x and #3x respectively. That is high-resolution displays demands images with higher density.
For example, if you want to display an image of size 128x128 in standard resolution. You have to supply the #2x and #3x size image of the same. ie., 256x256 at #2x version and 384x384 image at #3x version.
In the following screenshot, I have supplied an image of size 256x256 for 2x version to display a 128x128 pixel image in iPhone 6s. iPhone 6s render images at #2x size. Using the three version of images such as 1x, 2x and 3x with asset catalogue will resolve your issues. So the iPhone will automatically render the correct sized image automatically with the screen resolution.

Ideal image size for iOS

If I want to display an icon with 24x24 in an app, what sizes should I provide in the app?
For example, is it sufficient to save the image as 128x128 in the app?
Or are #1x #2x #3x sizes required?
It is a simple icon (width == height), example:
Different sizes are not necessarily required, but they can help reducing binary sizes.
For an image that you want to show in the dimensions of 24x24, you should provide a 24x24, a 48x48 and a 72x72 image.
For simple graphics like this, it's usually more suitable if you create a vector asset.

button image gets pixelated

I have designed a lock icon in Sketch to add to a button in my application:
I exported it both in pdf and png (2x, 3x) to add to Xcode assets. Problem is when I run the app on iPhone (SE), heavy pixelation can be seen around the edges of the icon:
I've tried both pdf and png formats, but result stays the same. Am I missing any settings that need to be applied for image to look sharp on screen?
Bigger is not necessarily better for a UIButton's image. Try to export your icon in more or less the same size with which it will be used. (Note that this also frees up memory in comparison to a way bigger image).
To adapt to different screens' resolutions, you should provide up to three images (#1x, #2x, #3x). You should read this excellent Apple's documentation on Image Size and Resolution. It explains perfectly how big should the images you provide in Xcode be.
They also have a good explanation on which format you should use according to the purpose of the image.
EDIT:
You can also use vector ressources (.pdf files for instance) that will render perfectly for any resolution. You can read this article about how to implement it in your Xcode project (If you do so, please be careful in the attributes of the asset to check Preserve Vector Data and the Scales to Single Scale, otherwise it may not render well).
It will happen if image sizes are not correct
check the size of images. 1x,2x and 3x sizes are should be as followed
1x = 24x24 px
2x = 48x48 px
3x = 72x72 px
If images size are too big than ImageView then pixelate will happen
Hope this will help you

iOS images sizes

I'm having doubts regarding the size of the images at different resolutions.
Example:
I have a button in the GUI I inserted it in size 100x50.
My background pictures for this button to 1x, 2x, 3x must be of sizes which? In px or pt?
I did some tests and insert them for their size 100x50 1x, 2x and 3x 300x150 200x100 (in px). But the images were of poor quality.
PS: I've seen the documentation but also those doubts were not very clear
You should use:
1x - 100*50px - image.png
2x - 200*100px - image#2x.png
3x - 300*150px - image#3x.png
I think problem with naming better you Use the assets catalog. Xcode will manage the #1x, #2x, #3x easilly or name the images properly as
image_name.png (for 1x image)
image_name#2x.png
image_name#3x.png
for more details about image resolutions take a looks on this and apple's ui guidlines
You can use a simple vector graphic, png or icns format. Now there a different options to convert your picture in hte #2 and #3 format. You can use e.g. the App 'Prepro' -> it's for free in the App Store. This App will create your needed icons

How important are non-retina images?

I'm releasing a new update for one of my apps and I was disappointed to see that it just barely surpasses 20MB estimated size (20MB is the point where it can no longer be downloaded over cell data).
My app contains a lot of images, so I could greatly reduce the size if I didn't have all those non-retina images. I know that there are some non-retina devices that will be running my app. So here are my questions:
How will a non-retina device react if I have an image with the #2x suffix but no non-retina image without it.
If I use a retina sized image without the #2x suffix and scale it down to the size I want to display it at programmatically and/or
through interface builder, will it still maintain full quality on
retina devices? Will the quality be worse on a non-retina device
than using an image I downscaled from the original using GIMP
instead?
How will a non-retina device react if I have an image with the #2x suffix but no non-retina i
image without it.
I use that approach on a couple of apps of mine and it works flawlessly. I am not able to detect any performance or visual issues on non-retina display devices (concretely, iPad 1/2 and mini).
I am not sure what can happen on older iOS version, since I only support iOS5+ on those apps.
If I use a retina sized image without the #2x suffix and scale it down to the size I want to display it at programmatically and/or through interface builder, will it still maintain full quality on retina devices? Will the quality be worse on a non-retina device than using an image I downscaled from the original using GIMP instead?
This comes down to how you set interpolation options while doing the scaling. See this other question for more details on how interpolation quality affects scaling down an image. In GIMP or Photoshop you also have control on the interpolation to be used for scaling, btw.
But in the end I don't think you need to go this way.
Most importantly, that bandwidth limit has been raised to 50MB.
OK.
If you only provide one image then you have one of two possibilities.
The image is a non-retina image. This will look fine on the non-retina. It will look identical on a retina device. But will look low quality next to a retina image.
The image is a retina image. On the retina device it will still load as a retina image. It will look fine. However, on the non-retina device it will have to scale down the image. This takes extra cycles of the CPU so could affect performance and it may not look how you want. It may shrink the image using a different method than you want and so may make the image look odd.
This is the same with or without a suffix.
The best solution is to create retina images and then use your editor of choice to create the standard versions. Nothing will stop you only providing one image but it may lead to a look and performance that you don't want.
On a side note. The size for downloading over cellular data was increased to 50MB.
Try these things using the simulator and find out for yourself.
I think the answer is that UIImage will ignore the #2x choice if you're relying on [UIImage imageNamed:#"without2xSuffix.png"] and not find anything, but I haven't tried it. Deliberately requesting the #2x file will work, but whether the image will be scaled, tiled, stretched or centered (or something else) is up to the place where it's used.
Note that the documentation says that unless you use the name without the #2x suffix and let iOS find the 2x version for you, it will set the scale of the image to 1.0 rather than 2.0, which complicates drawing. You'd have to load the image using imageWithData:scale: to fix this.

Resources