我正在拍摄一张图片,通过屏幕上下文加载它,并逐个像素地更改它。我有很多不同的滤镜我应用于图像,但我最后需要做的是移动色彩平衡(类似于Photoshop),使红色更加青色。
下面的代码显示了我如何拍摄图像,获取数据以及逐个像素地浏览r / g / b值:
CGImageRef sourceImage = theImage.image.CGImage;
CFDataRef theData;
theData = CGDataProviderCopyData(CGImageGetDataProvider(sourceImage));
UInt8 *pixelData = (UInt8 *) CFDataGetBytePtr(theData);
int dataLength = CFDataGetLength(theData);
int red = 0;
int green = 1;
int blue = 2;
for (int index = 0; index < dataLength; index += 4) {
int r = pixelData[index + red];
int g = pixelData[index + green];
int b = pixelData[index + blue];
// the color balancing would go here...
if (r < 0) r = 0;
if (g < 0) g = 0;
if (b < 0) b = 0;
if (r > 255) r = 255;
if (g > 255) g = 255;
if (b > 255) b = 255;
pixelData[index + red] = r;
pixelData[index + green] = g;
pixelData[index + blue] = b;
}
CGContextRef context;
context = CGBitmapContextCreate(pixelData,
CGImageGetWidth(sourceImage),
CGImageGetHeight(sourceImage),
8,
CGImageGetBytesPerRow(sourceImage),
CGImageGetColorSpace(sourceImage),
kCGImageAlphaPremultipliedLast);
CGImageRef newCGImage = CGBitmapContextCreateImage(context);
UIImage *newImage = [UIImage imageWithCGImage:newCGImage];
CGContextRelease(context);
CFRelease(theData);
CGImageRelease(newCGImage);
theImage.image = newImage;
我正在对像素数据进行许多其他操作(设置水平,去饱和)但我需要将红色值移向青色。
在Photoshop中,我可以通过以下方式完成:
图像:调整:色彩平衡 并将其设置为-30 0 0
我无法找到解释如何执行此色移的算法或示例。我试图从每个红色值中减去30,或者将最大硬度设置为255 - 30(225),但这些似乎会削减颜色并且不会改变值...现在,我只是在讨价还价,但指向参考的指针会有很多帮助。
(注意:我无法使用OpenGL解决方案,因为我必须使用相同的算法并将其转换为PHP / gd以获取此应用程序的Web服务器版本)
答案 0 :(得分:3)
您需要做的是减去红色然后校正“亮度”以匹配旧颜色,无论您选择什么样的亮度。这样的事情应该有效:
// First, calculate the current lightness.
float oldL = r * 0.30 + g * 0.59 + b * 0.11;
// Adjust the color components. This changes lightness.
r = r - 30;
if (r < 0) r = 0;
// Now correct the color back to the old lightness.
float newL = r * 0.30 + g * 0.59 + b * 0.11;
if (newL > 0) {
r = r * oldL / newL;
g = g * oldL / newL;
b = b * oldL / newL;
}
注意,当给出纯红色时,这会有些奇怪(它会保持不变)。 OTOH,GIMP(版本2.6.11)在其色彩平衡工具中做同样的事情,所以我不太担心它。