I try to write ToneCurveFilter using CoreImage. I have curves data in RGB image. Size of the RGB image with curves data is 256*1. Every pixel presents curve value. For example, for red = 200, you should get pixel with coordinates (200, 0) and get red channel from this pixel.
Image: http://i.stack.imgur.com/Njhr6.png
I exam colour of every pixel in the curve image, and they are correct. (Identical values, result filter shouldn't change image colour)
Also I write a kernel for the filter:
kernel vec4 coreImageKernel(uniform sampler src, __table sampler toneCurveData)
{
vec4 color = unpremultiply(sample(src, samplerCoord(src)));
//return vec4(color.r, color.g, color.b, 1.0);
vec2 redPointPosition = samplerTransform(toneCurveData, vec2(color.r * 255.0, 0.5));
float red = (sample(toneCurveData, redPointPosition)).r;
vec2 greenPointPosition = samplerTransform(toneCurveData,vec2(color.g * 255.0, 0.5));
float green = (sample(toneCurveData, greenPointPosition)).g;
vec2 bluePointPosition = samplerTransform(toneCurveData,vec2(color.b * 255.0, 0.5));
float blue = (sample(toneCurveData, bluePointPosition)).b;
vec4 resultColor = vec4(red, green, blue, color.a);
return premultiply(resultColor);
}
I expect that this filter, will not change my source image. But a result image is more darker then the original image.
I've tried change color.x * 255.0 to concreate value, for example to 230.0, but color of the result image was (224, 223, 224). And I do not understand why.
To test my kernels I use "Quartz Composer" -- very useful tool.
I've tried add ROI function, but this is not helped for me.
function myROIFunction(samplerIndex, dstRect, __image info) {
__vec4 dstRectResult = dstRect;
if(samplerIndex == 1)
{
dstRectResult = info.extent;
}
return dstRectResult;
}
function __image main(__image src, __image toneCurveData, __color monohromeColor, __number power) {
coreImageKernel.ROIHandler = myROIFunction;
return coreImageKernel.apply(src.definition, toneCurveData, src, toneCurveData, monohromeColor, power);
}
I think problem in coordinate space of toneCurveData sample, but I can't understand what exactly.
Main question: how get a pixel colour from toneCurveData for some pixel (for example, for pixel with coordinates (255.0, 0.0), it should be (255.0, 255.0, 255.0))?
Also I've tryed use a NSData object with toneCurve data as parameter of the kernel, this's not helped me.
I've created a RGB tone curve filter in one of my recent projects. You can find it here https://github.com/YuAo/YUCIHighPassSkinSmoothing
Instead of requiring a curve image, I make the filter generate the curve texture itself based on a set of control points.
I think your problem may be using a tone curve image. Core Image by default does not use color management. You might lose some detail or color fidelity of the tone curve image. You can try to create the CIContext object with a "device RGB" working color space:
[CIContext contextWithOptions:@{kCIContextWorkingColorSpace:(id)CFBridgingRelease(CGColorSpaceCreateDeviceRGB())}];