By adapting the formula from this page: http://http.developer.nvidia.com/GPUGems/gpugems_ch22.html, I believe you can do this using a combination of CIColorMatrix
, CIGammaAdjust
and another CIColorMatrix
.
Let's call the input levels inBlack
, inGamma
and inWhite
respectively, and the output levels outBlack
and outWhite
. Note that Photoshop color are between 0 and 255 while CI colors are between 0 and 1 so you need to divide the Photoshop values (except inGamma
!) by 255 before putting them into the following formulas.
The input mapping is pixel = (inPixel-inBlack)/(inWhite-inBlack)
, which means your first matrix will be
red = [1/(inWhite-inBlack) 0 0 0]
green = [0 1/(inWhite-inBlack) 0 0]
blue = [0 0 1/(inWhite-inBlack) 0]
alpha = [0 0 0 1]
bias = [-inBlack/(inWhite-inBlack), -inBlack/(inWhite-inBlack),-inBlack/(inWhite-inBlack), 0]
Then you apply gamma correction using CIGammaAdjust
and the inGamma
number (I had to use the inverse 1/inGamma
when doing my calculations, try that too!).
Finally the output mapping is pixel = gammaCorrectedPixel * (outWhite - outBlack) + outBlack
, giving you the final matrix
red = [(outWhite - outBlack) 0 0 0]
green = [0 (outWhite - outBlack) 0 0]
blue = [0 0 (outWhite - outBlack) 0]
alpha = [0 0 0 1]
bias = [outBlack outBlack outBlack 0]
I haven't actually tried this using CoreImage, but the calculations work out nicely!