Is adding #2x or #1x image required - ios

If I have #3x image and all I need to do is downscale that image to create #2x and #1x, why am I required to add them? I see some UIImage functions just downscale #3x image on the device whereas other UIImage functions fail if #2x image is not there. I find it very time consuming to downscale so many images and add them to project every time. Is there a workaround?
Edit: To make it more clear, my question is UIImage imageWithContentsOfFile returns nil if I only supply #3x without supplying #2x. But UIImage imageNamed works. Is that normal, or I am doing something wrong?

Not sure exactly what you need to do or how you are using the scaled images... or even if they are photos or icons.
If you are using these images as icons, add them to an asset folder. Then the assets can be referenced by name within a control on a storyboard. Easy.
For creating buttons, let’s say a 40x40 button, I create the icon, 40 x 40, in Inkpad and save the result as a PDF file. Then I put that in an image asset and select the option for only one image. Since it is a vector drawing, it scales up nice.
If you are using the same images in multiple apps, I would recommend creating an assets folder called something like Common_Images and just copy that folder from one app to another. Deliriously quick & easy,
I wrote a quick and simple app that lets the user pick a photo, type in the 1x width and height, press a button and done! Doing this on a Simulator lets me quickly drag and drop these new scaled pics right into an image asset within Xcode. Quick and simple.

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.

Sprite Atlas - Importing #3x, #2x, and #1x images into XCAssets

I have a script that I wrote that takes a folder of images, and automatically resizes them to the #3x, #2x, and #1x equivalents.
I named the folders #3x, #2x, #1x, and inside each folder every image has a suffix of #3x.png, #2x.png, #1x.png, respectively. (So for example bouncing-ball-frame-1#3x.png resides in the #3x folder)
The way I used to import images was just this:
Manually create a new sprite atlas folder in XCAssets using the "+" button in Xcode
Manually drag and drop the #3x images into this folder. Xcode will then use these images as their #3x versions.
Manually (1 by 1) move each #2x image, and each #1x image, into their respective "slots" next to the #3x image.
But now that I have tons of images i'll be using, this is just a lot of work for me.
I was hoping I could just drag and drop an entire folder into XCAssets (with all of the 3x,2x,1x images), and Xcode would automatically put each image where it belongs in one giant sprite atlas.
Is this sort of thing possible? I could've sworn I read somewhere that if you name the folders/images a certain naming convention, and suffix the parent as .atlas, then it does this all for you without having to manually do it.
Could anyone offer advice/solution for this?
Thanks!
I figured out how to do this, and wanted to share:
You create a new atlas within Xcode, and remove the default image it gives you.
..Now, create a folder on your computer, and put all of the images in there. EVERY image. The 1x, the 2x, and the 3x.
The naming conventions should be like this (assume my images are 25 frames like bouncing-ball-1.png, bouncing-ball-2.png, etc)
bouncing-ball-1.png would be the 1x version (notice the absence of 1x?)
bouncing-ball-1#2x.png
bouncing-ball-1#3x.png
If you had 25 frames of animation, you'd have 75 images in one folder.
Then you drag all 25 of these files to your target xcassets/ folder I mentioned above, and you're done.
Xcode will look at bouncing-ball-1, bouncing-ball-1#2x, bouncing-ball-1#3x, ..., etc, and create 1 image for all 3 sizes (so in my case 25)

WatchKit Force Menu Custom Icons Blurry

I'm creating custom icons for the WatchKit Force Menu. The documentation says to use an 80 x 80 size image with a drawing area of 54px square. All that works fine, but my image, when displayed in the button, looks very blurry compared to the built-in button images.
I'm creating them in Illustrator at 80px square. Saving as a .png image like the documentation says. Sizing is correct when saved at 72 dpi. If I do anything higher it causes the image in the button to be too large. I cannot find a way to scale the image.
Has anyone run into this? It seems like I would want to use a higher resolution image here or vector graphics.
You need to save the file with #2x in the filename to support retina displays.
So if your filename is myicon.png rename it to myicon#2x.png. In code you just use myicon for the name, Xcode automatically picks the correct size.
For iPhone 6, #3x is required...
I would recommend to use the Images.xcassets in Xcode for maintaining all images. There are templates for all needed resolutions (#1x, #2x, #3x, ...). Create the icons in these several resolutions and drag the files from finder to the placeholders. Later in your code you simply use the name of the image set in Xcassets.

Xcode 6 asset catalog automatically create images for smaller scales

With the need of 3x images in iOS 8 I figured it would be easier to manage images with an asset catalog in Xcode 6. I am trying to just provide a single image, the 3x scaled image to the asset catalog and I want Xcode to automatically downscale that image to generate 2x and 1x versions of the 3x image, so that I don't have to do it manually.
Right now this is what I have:
I really hope that Xcode has such a feature to automatically create 2x and 1x images and I just have not discovered it yet. If there isn't any such feature, are there any alternatives? (I know IconKit but it is annoying and hasn't been updated to support 3x images. If it was made properly in the first place it wouldn't even need an update..)
I know that Xcode automatically can generate all images from a vector pdf, but thats not what I am looking for!
I ended up making a small mac app that takes care of the dirty work. You can drag and drop one or multiple .jpg or .png files into the app's main view; it will detect the input image's scale and create the smaller scaled images. With this app I only need to create a single, 3x image and drag it into the app to create the two smaller images. It saves so much work!
The source can be found on my GitHub page, simply download it and run it on your mac! https://github.com/JonasGessner/ImageReducer
There is another way to solve this problem.
Use Automator to create Mac OS X service which create #3x, #2x and normal image on base of 1 image in #3x resolution automatically. It use just 3 methods: duplicate images, scale down, and rename.
Ready Mac OS X service made in Automator you can find here:
https://github.com/lukszar/iOS-Images-Prepare
late to the party but there is one tool which make all assets #1x, #2x, #3x and icons for you in just one click. And also export to XCAssets file.
You can find it here: https://github.com/angelvasa/AVXCAssets-Generator
Hope this will help someone
If you do not provide 1x or 2x assets, and your app is run on a 1x or 2x device, it should downsample the 3x asset at runtime. This may look fine, but depending on the scaling method used, it may also look really bad, so make sure this is really what you want.
If a folder named *.imageset, and the contents in it is well organized, Xcode will actually recognize them as an image. So this is another way to do this: https://github.com/albert-zhang/gen_xcassets
This python script will quickly auto generate #2x version for all images in a folder.

How to use images sliced with the slicing tool of the XCode5 assets catalog

In the assets catalog in the new XCode5 there's a tool to slice your images, I assume this is used for images that are going to be stretched, and it has the same effect as using the resizableImageWithCapInsets: method on a UIImage object.
My question is, once I sliced my image, how do I use it in my code? I just create the image with the size I want and it's stretched automatically using the insents I set in the slicing tool? Or I have to create it using a special way?
I haven't found any documentation about it yet.
The image slicing in Xcode 5 works with [UIImage imageNamed:#"blah"];. You don't have to do anything in the code. The slicing information is automagically contained in the UIImage that gets returned.
You can set everything using the asset catalog: retina, iPad, slicing, etc...
Then give the whole set of images a name and just use that name.
Your app will then pull out the correct image from the catalog including all the slicing information.

Resources