[英]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)? 给定CGImage或UIImage,如何应用自定义颜色查找表(也称为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. 我将描述您可以采取的三种方法。
First, get the raw image data from the UIImage. 首先,从UIImage获取原始图像数据。 You may do this by creating a byte array of the appropriate size (width * height * components), then drawing into it with CGBitmapContext. 您可以通过创建适当大小的字节数组(width * height * components),然后使用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
. 您可以通过从字节构造CGDataProvider
,然后CGImage
,然后从CGImage
UIImage
,将输出字节转换为图像。
As of iOS 5, Apple provides many built-in image operations. 从iOS 5开始,Apple提供了许多内置的图像操作。 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. 给定一个CIFilter,您可以设置inputImage,然后从OutputImage
属性中检索输出。 See the documentation for a list of filters in the CICategoryColorAdjustment and CICategoryColorEffect categories. 有关CICategoryColorAdjustment和CICategoryColorEffect类别中的过滤器列表,请参阅文档 。 As of this writing, I would suggest looking at CIToneCurve, CIFalseColor, CIColorMap and CIColorCube. 在撰写本文时,我建议您查看CIToneCurve,CIFalseColor,CIColorMap和CIColorCube。 Sadly, at the time of writing, CIColorMap is not available on iOS. 可悲的是,在撰写本文时,CIColorMap在iOS上不可用。
If you are doing scientific imaging, and you only use a linear gradient between two colors, I suggest looking at CIFalseColor . 如果您正在进行科学成像,并且您只使用两种颜色之间的线性渐变,我建议您查看CIFalseColor 。
Here is an example of populating a CIColorCube with a random color look-up function. 以下是使用随机颜色查找功能填充CIColorCube的示例。 Note that CIFilters may be created dynamically by name (not type-safe) or in a strongly-typed way. 请注意,可以按名称(非类型安全)或强类型方式动态创建CIFilter。 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")
). 如果你知道在代码时想要使用什么过滤器,我建议使用强类型过滤器( CIColorCube
而不是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);
}
Finally, the most general-purpose high-performance approach that remains correct under magnification would be to do the color mapping on the GPU. 最后,在放大率下保持正确的最通用的高性能方法是在GPU上进行颜色映射。 This is more effort than the first two approaches, so you need to decide if it is worth it. 这比前两种方法更省力,所以你需要决定它是否值得。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.