So I added my images as vector PDFs to the assets since I thought this should get me the highest quality. But when I actually use them as button images they show up very aliased:
But if I replace the vector PDFs with PNGs the size of 50x50px for 2x and 100x100px for 3x, I get a perfect image without any aliasing:
But why is this? Is there any way to get the vector image smoother? And if not why would you use vector images at all?
Btw, my code is nothing special I just set the button image somewhat like this, but in Xamarin.Ios:
myBtn.setImage( UIImage.init(named: "imagename"), for: .selected)
Also note that the reason the white background isn't there in the second image is, because I removed it when I created the PNGs.
In Xcode in your assets catalog select your PDF image, then on the inspector pane (right one), check the box 'Preserve Vector Data'.
It could be hidden when using Xamarin.iOS, documentation can be found here.
Related
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.
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
In my project I am using an image asset that is based on a PDF icon:
I am now using this image in a UIButton but the image takes up too much space. Is there an elegant way to set the size of the image:
Xcode converts PDF image assets to bitmaps at build time, so at runtime you actually aren't dealing with a vector image. Hence you can't actually do perfect scaling. For this reason it's best to have a separate image asset for your button if its size is different.
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.
I am creating a button for my application that, when pressed shows an indention looking effect to make it appear that the user is clicking a real button. It is very simple, using only an image for the default state and the depressed one for the highlighted state. I'm having a few problems. The quality is terrible. I have uploaded the images to XCode in the exact pixels they will be presented in my application but when I export it from Illustrator it gets really pixelated. So I was wondering if there was a way for me to upload an image a few times bigger than my button and have it shrink to fit the button size. I've tried to do that but when I run my app it gets really messed up and weird looking. I would just put text inside the button but then it ruins the pressed effect. Any ideas?
If you export an image at the same aspect ratio as the button, the image will be re-scaled to fit within your button. Don't forget to use the Custom style so you don't get the button oval.
However generating an exact pixel version of your button should be possible, and look good - especially if you specify a 2x sized #2x version of the image for retina use. Are you sure your Illustrator export settings are correct? One thing to consider is that perhaps anti-aliasing needs to be enabled on export.
This page has a helpful quick checklist for how to save for the iPhone from Illustrator (Scroll down to the "How To Save Art For The iPhone In Illustrator" header)
http://www.vickiwenderlich.com/2011/11/faq-how-do-i-save-art-for-the-iphoneipad/