Use icns file as an image in iOS - ios

Is there a way to use an icns file as the image source for I guess a UIImage? Or pick out one of the representations and resize?
NSImage does not seem to be available in cocoa-touch.
In particular I'd like to use them for drawing in the imageView part of a UITableViewCell.

There is no built-in way to do this and I see little benefit in doing so. It's best to just use the sizes that you need and ship them as individual images in your app. If you want to draw the images in a UITableViewCell, performance is an important aspect and resizing images won't be fast.
If you really need images in many different sizes and really don't want the best performance by including images for each size, you could use a PDF to make use of vector graphics. There is a nice article about this technique: http://mattgemmell.com/2012/02/10/using-pdf-images-in-ios-apps/
Honestly, don't try to use .icns files in your iOS app. It's just a container for images of different sizes and resizing is not a good idea, anyway. Either include individual images for any size you need or use vector graphics using a PDF file.

Related

Is there a way to compress a pdf made with pdfkit?

I’m using pdfkit to create multi-page documents with embedded images, and the files get really large quickly. I can compress them nicely afterwards using Preview on the Mac, and they still look great, so I’m wondering if there is perhaps a setting I’m missing in pdfkit that controls resolution or size, or if there is way to compress them after creating them.
No, there isn't a way of specifying the image compression using PDFKit. It's just putting the image data in a PDF wrapper.
I'd suggest that you probably don't want to reduce the size of the image; but just the compression level. However, if you do, you can use CGPDFDocument and scale the image to fit a particular-sized graphic context.
On macOS, it is possible to create a Quartz Filter programmatically, which can include options for compression, which you can then apply in the options when you write your PDF; but this isn't available in iOS.
(If you're using macOS's 'Reduce File Size' Quartz Filter when exporting from Preview, it's well-known to be not very good; many people have made better ones.)
However, you can set the JPEG compression level in a UIImage object, so you may be able to increase the compression in the image data before you convert it to PDF.
https://developer.apple.com/documentation/uikit/uiimage/1624115-jpegdata/

SVGKit performance and should it be preferred over PNG?

I have been looking at SVGKit and I am finding conflicting ideas. Some say it's slower than PNG and others saying it is fast.
I was hoping to get a recommendation and which route I should take. When I am exporting my vector graphics to PNG for display, would it not make sense to use an SVG instead ?
Of course this gives the added value that it remains a vector.
Or is it still recommended in exporting everything to a PNG ?
You might consider the middle-way introduced in Xcode 7. Here you add your assets to the project as vector images (PDF) and at build-time Xcode automatically generates the PNGs in all needed sizes (1x, 2x, 3x).
Personally, I only use SVGs when necessary, like if I need to be able to change the color of the (parts of the) image. I believe there can be a performance hit when resizing vector images at run-time, although Android uses vectors as default, so it might be insignificant.
SVG is most resource intensive and can be used if you need to display something that can be zoomed in and out while PNG should be preferred for most UI graphics (logos, icons, etc.), as it is crisp yet remains lightweight and fast to display so there is no way to compare SVG with PNG in term of Performance.
if you are going after a Crystal clear images you can use pdf based graphics, which are supported by Xcode Using Vector Images in Xcode
if you still need to implement SVGKit i always suggest using some tools (like SVGCleaner) to clean and simplify SVG in order to enhance performance.

UIImage size managment

I have an image that is used in multiple places within my IOS app at various sizes. Should I be using one large image in conjunction with UIViewContentModeScaleAspectFit to scale it (currently this approach seems to cause distortion on the smaller images despite being scaled to proportionate sizes) or should I have multiple versions of the image at different sizes.
It seems a little extreme to have so many copies of one image e.g. my_image_ipad, my_image_small, my_image_large, my_image_medium.
In general it depends on what it takes to get the look and quality you want. Some images will scale from a large image to a small image with little or no visual loss in quality. Others, as you've found, scale poorly, especially at extreme scales. You're really going to have to just try various solutions and see what works. One way you can almost always cut down on application size is to remove the non-#2x artwork and ship with just the #2x.
It is better to use one image, because it will make your app "lighter", but this may cause your code to become bigger.

What are the ways to reduce bundle size on iOS?

I have some images which are huge in size and my bundle size currently is 70 MB. I think Xcode already runs the assets through png crush.
Do not use any text images with useless effects, use UILabels instead.
Draw simple shapes and effects using CAShapeLayers instead of using
images.
Use JPEGs instead of PNGs where you don't need transparency.
(Actually file size depends on the image content here)
Use Save for Web option in PhotoShop or other tools to optimize PNG
images.
Use sprites combined together instead of separate images.
Make sure you delete all unused resources.
Do not localize common parts of the images, localize only the
different parts. (think of a background image with a small flag at
the bottom for each locale. use one single bg image and separate flag
images. localize flag images only, not the entire bg images with the
flags.)
Use the same splash images for iOS7 and previous iOS versions. (You
need to manually edit the JSON file in .xcassets)
Try using a CDN to download assets on the first launch.
In addition to images keep those in mind too:
Try replacing custom fonts with default system fonts if you don't
need them really.
Use MP3 audio files instead of WAV files. (or other
compressed formats)
Make sure you delete all unused 3rd party frameworks.
You can try converting the images to jpg (if they don't have any transparent regions).
Also try using http://imageoptim.com/
It seems very unlikely that you actually need huge images. After all, the screen is not huge. Thus, the most likely form of size reduction is to reduce the physical dimensions of the images to the size you are actually going to be displaying.
This saves bandwidth when the user downloads the image, reduces the size of the app on the user's hard disk (the device), and also saves memory at the time an image is loaded. It is a vast waste of RAM to load an image that is larger than the size at which it will be displayed; after all, remember, the memory involved rises exponentially with the square of the difference.
One option is to host the images on a CDN like OpenText and fetch them as part of app initialization, or whenever they are first needed. Obviously this is more coding, but projects like SDWebImage make it pretty easy:
https://github.com/rs/SDWebImage/tree/master/SDWebImage
It also gives you the flexibility to swap out those images later if you use caching headers.

Interface building - UIViews vs Images vs Core graphics vs PDF subclass

My app uses flat graphics, which mostly consists of lines and flat surfaces...
Whats the best approach for building the UI?
use PNG images as much as possible (like for the attached picture, the whole background would be an image)
use 4 UIViews (in this example case) with background color to make the background and the 3 lines
use CoreGraphics to actually draw in drawRect (or somewhere else?)?
subclass UIView and draw PDF content
any other approach?
What are the performance impacts? The advantage of the first two, is that they can be done in IB, but is there a downside (like performance or quality or caching)? I also heard of a trend of using CoreGraphics for drawing all the time...
So basically the fastest way is to use PNG files (stretchable and normal), also if you are using PNG files it will be easy to change the design and fix eventual bugs.
When you are using PNG files, try to reduce the size of the PNGs (stretchable images for backgrounds) for a better performance and a small size of the app.
CoreGraphics is more complex and can add strange bugs or performance problems if you don't know what you are doing, but can be use also for simple view styling.
On every project that I've done I couldn't use only one of these two because of the project complexity or because I was to lazy to open photoshop and add extract some designs.
As H2CO3 said is not that simple. Each format suits particular requirements, there are no written laws, I just ca tell you what I do.
Small pieces of UI, such as buttons, icons etc: I normally use PNG or PDF. You can subclass a UIView to draw PDF vector content. The plus with PDF is that if the source is a vector image, you could not take care about physical-logical points.
Images or Hi-res images, such as image of a content: In this case I use JPG, for they small size respect of PNG. They take little bit more to decompress but usually the size is very smaller compared to PNG.
In general PNG can use alpha, JPG no
Image is a big topic, nowadays I always try a way to find symmetry in UI elements and use stretchable UIImages with PNG.
For you example I will use PNG witch stretchable left and right side. Instead of use 640 px image, you can use 10 px image, with stretchable right margin and stretchable left margin.
[update]
It should be said that if you use stretchable images you will get a lot of performance boost, since the image will be smaller, you will occupy less memory on the "disk", less memory on the heap thatnks to the GPU stretching and less decompressing times
.

Resources