Detecting faces in a UIImage

In iOS the task of detecting faces in a UIImage is a relatively simple task thanks to the CoreImage framework.

However there are a couple of gotchas to be avoided:

  • The coordinate space for images in the CoreGraphics and CoreImage frameworks are different.
  • The orientation of the source image is important — the CoreImage API will not be able to recognize faces at extreme angles.

With these caveats in mind the following is a utility class for identifying faces in an image.

Creating dynamic stickers for iMessage

An iMessage extension is a mechanism that allows an iOS app to surface content to users in the iMessage SMS/messaging application.

Implementing an iMessage extension is an excellent way to engage users on an app surface frequented regularly by users.

A core feature of iMessage extensions is the ability to create stickers in conversations. Stickers have pre-requisite requirements: they must be less than 500KB is size and they should optimally be one of a fixed set of dimensions:

    • Small: 300 x 300 px
    • Medium: 408 x 408 px
    • Large: 618 x 618 px

In this post we will tackle the challenge of converting an arbitrary UIImage to a MSSticker in Swift. If you would like to try an iMessage app using dynamically created stickers checkout Emojoy on the AppStore.

The first step is to find the appropriate sticker dimensions. We want to avoid scaling to a larger dimension as this introduces fuzziness and/or pixelation.

Next want to aspect fit the image to the closest smaller dimensions. This will avoid any stretching or cropping of the image. If the source image is smaller than the smallest optimal sticker size we will leave it as-is. The Message framework will handle sizing it itself. The key benefit of performing this sizing step is to ensure we meet the 500KB maximum file size requirement for a MSSticker.

The third step is to attempt to create a lossless image file for the sticker from the adjusted UIImage. If the file meets the size requirement then we are done!

If the file size is too large we have 2 options: attempt to create a sticker with a smaller dimension or use a lossy (JPEG) encoding for the sticker file. We would prefer the latter however this is not possible if the source UIImage has an alpha channel (a JPEG encoding does not support an alpha transparency channel for images).

Finally, with all this implemented within a UIImage extension we can create a MSSticker from a UIImage easily without worrying about the details.

View the complete code listing here.