Given a CGImage or UIImage, how can I apply a custom color look-up table (aka LUT, CLUT, Color Map)? That is, how can I map the colors in the image to new colors, given a mapping?
Share
Sign Up to our social questions and Answers Engine to ask questions, answer people’s questions, and connect with other people.
Login to our social questions & Answers Engine to ask questions answer people’s questions & connect with other people.
Lost your password? Please enter your email address. You will receive a link and will create a new password via email.
Please briefly explain why you feel this question should be reported.
Please briefly explain why you feel this answer should be reported.
Please briefly explain why you feel this user should be reported.
I will describe three approaches that you can take.
Manual Approach
First, get the raw image data from the UIImage. You may do this by creating a byte array of the appropriate size (width * height * components), then drawing into it with CGBitmapContext. Something like this:
Then create an array of bytes for your output image (probably the same size). Iterate over the input image looking up color values in your Look-Up Table and writing them to the output image.
You may convert the output bytes to an image by constructing a
CGDataProviderfrom the bytes, then aCGImagefrom that, and then aUIImagefrom theCGImage.CIFilter Approach
As of iOS 5, Apple provides many built-in image operations. Generally, these are easy to use and faster than doing it manually. However, depending on how your color look-up table is specified, you might not find a perfect fit.
Given a CIFilter, you may set the inputImage, then retrieve the output from the
OutputImageproperty. See the documentation for a list of filters in the CICategoryColorAdjustment and CICategoryColorEffect categories. As of this writing, I would suggest looking at CIToneCurve, CIFalseColor, CIColorMap and CIColorCube. Sadly, at the time of writing, CIColorMap is not available on iOS.If you are doing scientific imaging, and you only use a linear gradient between two colors, I suggest looking at CIFalseColor.
Here is an example of populating a CIColorCube with a random color look-up function. Note that CIFilters may be created dynamically by name (not type-safe) or in a strongly-typed way. If you know what filter you want to use at code-time, I suggest using the strongly-typed filter (
CIColorCuberather thanCIFilter.FromName("CIColorCube")). I am using the dynamic approach in the following example, as it is more confusing.GPU Shader Approach
Finally, the most general-purpose high-performance approach that remains correct under magnification would be to do the color mapping on the GPU. This is more effort than the first two approaches, so you need to decide if it is worth it.