简体   繁体   中英

How do I apply a LUT (Color Look-Up Table) to a CGImage or UIImage in IOS?

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?

I will describe three approaches that you can take.

  1. Do it manually
  2. Use a CIFilter (available in iOS 5)
  3. Use a shader (GPU program)

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:

    using (var colorSpace = CGColorSpace.CreateDeviceRGB())
    using (var context = new CGBitmapContext(
        bytes, width, height, bitsPerComponent, bytesPerRow, 
        colorSpace, CGBitmapFlags.ByteOrder32Big | CGBitmapFlags.PremultipliedLast))
    {
        var drawRect = new RectangleF(-rectangle.X, -rectangle.Y, image.CGImage.Width, image.CGImage.Height);
        context.ClipToRect(new RectangleF(0, 0, width, height));
        context.DrawImage(drawRect, image.CGImage);
    }

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 CGDataProvider from the bytes, then a CGImage from that, and then a UIImage from the CGImage .

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 OutputImage property. 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 ( CIColorCube rather than CIFilter.FromName("CIColorCube") ). I am using the dynamic approach in the following example, as it is more confusing.

static void PopulateColorCubeFilter(CIFilter filter)
{
    if (filter.Name != "CIColorCube")
        return;

    int dimension = 64;  // Must be power of 2, max of 128 (max of 64 on ios)
    int cubeDataSize = 4 * dimension * dimension * dimension;
    filter[new NSString("inputCubeDimension")] = new NSNumber(dimension);

    // 2 : 32 /4 = 8 = 2^3
    // 4 : 256 /4 = 64 = 4^3
    // 8 : 2048 /4 = 512 = 8^3

    var cubeData = new byte[cubeDataSize];
    var rnd = new Random();
    rnd.NextBytes(cubeData);
    for (int i = 3; i < cubeDataSize; i += 4)
        cubeData[i] = 255;
    filter[new NSString("inputCubeData")] = NSData.FromArray(cubeData);
}

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.

  1. Load one texture map (aka Sampler2D) with your input image
  2. Load a second texture map with your color map (practically it is a 1D Texture, but with OpenGL ES probably needs to be loaded as a 2D Texture)
  3. Apply the two texture maps and a shader to a quad
  4. In the shader use the texture coordinates to look up the color in the first texture, then use the value in the first texture to look up in the second texture. That is your output color.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM