UIImage Dithering

Hi everyone

Just getting strated with Swift and iOS.


I'm looking to create a dithered version of an image in iOS.

I've captured the image to a UIImageView and have converted to greyscale, with export options to photos.


imagepicked.image = convertToGrayScale(image: image) //make greyscale, working.


imagepicked.image = simpleDitherExample(inputImage: image) //where do I start?

To create a dithered image like this:

https://en.wikipedia.org/wiki/Dither#/media/File:Michelangelo's_David_-_Floyd-Steinberg.png


I understand that the CIDither isn't available until iOS 13, any options now? Any free iOS libraries I can import and call?


Any help appreciated.

Thanks.


XCode 10.2.1

iPhone 7

Accepted Reply

Hello,


The CIDither filter is actually available as of iOS 12. To use this filter pre iOS 13 (without the convenience of the CIDither protocol), you can do something like the following:


let filterParameters: [String: Any] = [
            "inputImage": inputImage, // a CIImage
            "inputIntensity": 2.0  // numbers in the range of 0.0 to 5.0 are valid
        ]
let ditherFilter = CIFilter(name: "CIDither", parameters: filterParameters)

Replies

Hello,


The CIDither filter is actually available as of iOS 12. To use this filter pre iOS 13 (without the convenience of the CIDither protocol), you can do something like the following:


let filterParameters: [String: Any] = [
            "inputImage": inputImage, // a CIImage
            "inputIntensity": 2.0  // numbers in the range of 0.0 to 5.0 are valid
        ]
let ditherFilter = CIFilter(name: "CIDither", parameters: filterParameters)

I'm afraid the CIDither CIFilter does nothing more than introduce pseudo-random noise (clear pixels) in the image and doesn't deliver any of the value of other dithering algorithms which can reduce the color palette while attempting to retain perceptual quality. This is really valuable for converting a full color image into something that can be encoded with GIF or PNG8 which are palette based (with a maximum palette of any 256 colors from the normal 24-bit RGB spectrum, 32-bit RGBA spectrum if you count PNG8's support of alpha).


A CIFilter that could automatically compute an optimal palette for a given limit of colors (8-bit=256, 7-bit=128, 6-bit=64, 5-bit=32, 4-bit=16, 3-bit=8, 2-bit=4, and 1-bit=2 [aka black and white dots]) then apply a dithering algorithm such as Floyd–Steinberg dithering, or Atkinson dithering (developed while Bill was at Apple, though 1-bit only), or even the very modern Simple gradient-based error-diffusion method would be a very welcome addition CIFilters.


Unfortunately, CIDither is not useful other than introducing artificial noise.