CILinearGradient not linear?
-
Ok, hopefully this is just me and I'm overlooking some Core Image
setting. :)
Create a linear gradient in Core Image Fun House:
/Developer/Examples/Quartz/Core Image/FunHouse
and compare it to CTGradient which uses Core Graphics (set the test
app to the default style):
http://blog.oofn.net/projects/misc
Compare with a Photoshop gradient if you like.
The CTGradient looks almost identical to the Photoshop gradient but
the Core Image gradient differs quite a bit... showing more lighter
tones and then dropping to black very quickly at the end. The
midpoint is 32% black instead of 50%.
Could this possibly be my machine/video card (ati 9600xt)? A monitor
color profile affecting core image?
Actually, I just noticed the example pic in the Core Image
documentation also exhibits the sharp drop to black:
http://developer.apple.com/documentation/GraphicsImaging/Conceptual/
CoreImaging/ci_filters/chapter_5_section_10.html
And, I created a CIContext that used the CPU rather than GPU and got
identical results:
http://developer.apple.com/qa/qa2005/qa1416.html
Hmmmm.
George -
George Orthwein wrote:
> The CTGradient looks almost identical to the Photoshop gradient but
> the Core Image gradient differs quite a bit... showing more lighter
> tones and then dropping to black very quickly at the end. The
> midpoint is 32% black instead of 50%.
A wild guess without any knowledge about Core Image whatsoever (and
without having tried out your suggestions):
It seems that both gradients are actually "linear", they're just
linear to different quantities.
The CT and Photoshop gradients are probably linear in the pixel
values they send to video hardware - 0 for black, 255 for white, and
128 for the middle gray in the center. Incidentally, this is also
approximately linear in perceived brightness.
The CI gradient is probably linear in actual physical light
intensity. Try comparing this gradient with a checkerboard pattern of
white and black pixels (if you're on an LCD, on a CRT use alternating
white and black horizontal lines), you'll see that it approximately
matches the brightness in the middle of the gradient.
On a properly calibrated Mac display, the relationship is that
light_intensity = pixel_value ^ 1.8, with both quantities measured
from 0 to 1. In your example: 0.5 = 0.68 ^ 1.8, with 0.68 being the
complement of your "32% black".
If this sounds all greek to you, read up on "gamma", especially
<http://www.poynton.com/notes/colour_and_gamma/GammaFAQ.html>, or on
colorimetry in general. It's a wide and not completely trivial field,
but understanding it helps a lot if you're seriously interested in
computer graphics.
-Christian -
I wanted to follow up this thread with the solution, even though I
also posted to quartz-dev.
CIContext does indeed default to a colorspace with a linear gamma
(1.0). The remedy is to create a context with a "normal" gamma using
kCGColorSpaceGenericRGB:
CGColorSpaceRef colorSpace = CGColorSpaceCreateWithName
(kCGColorSpaceGenericRGB);
NSDictionary *contextOptions = [NSDictionary
dictionaryWithObjectsAndKeys:(id)colorSpace,
kCIContextWorkingColorSpace, (id)colorSpace,
kCIContextOutputColorSpace,nil];
myCIContext = [CIContext contextWithCGContext:[[NSGraphicsContext
currentContext] graphicsPort] options:contextOptions];
I've created a test app showing the differences:
http://home.comcast.net/~george.o/CITooLinearGradient.html
I plan to file a doc enhancement request as I don't believe it
behaves as expected. In fact, I bet most people are unknowingly using
it as is, effectively creating non-linear gradients, even though
technically they are linear for a specific colorspace.
(Also, as far as I can tell, this issue only affects the gradient
filters.)
Hope this helps someone!
George



