Split tone effect using core image filters?
Asked Answered
P

2

13

I understand the principles behind the split tone effect, and would love to use either a color map or tone curves for individual rgb channels. Unfortunately that's not an option for iOS at the moment, as the SDK does not include those filters.

The only hack I've come up with (other than doing a render through opengl) is duplicating an image, adjusting hue in the highlights in one, shadows in the other, and combining them. However, I would prefer a simpler way that does not require a two-chain composite operation.

Is such an effect possible with a chain of any of the currently available core image filters in iOS 5?

Pattiepattin answered 1/11, 2011 at 2:41 Comment(1)
hi, can u please share how did you create CIColorCube data ?Deaton
C
3

I've been reading a little about how to do this in Photoshop, and it's basically increasing the contrast in the red and green channels and decreasing it in the blue channels. (At least for a basic effect - if you really do it with film, you can get some really odd color shifts, too!)

You can do contrast adjustment using a series of CIColorMatrix nodes. Contrast is basically ((value - 0.5) * contrast) + 0.5. So a color matrix for, say, a contrast of 1.5 in red and green, and 0.66 in blue, would be something like

| 1 0 0 -0.5 |   | 1.5 0.0 0    0 |   | 1 0 0 0.5 |
| 0 1 0 -0.5 | + | 0   1.5 0    0 | + | 0 1 0 0.5 |
| 0 0 1 -0.5 |   | 0   0.0 0.66 0 |   | 0 0 1 0.5 |
| 0 0 0  1.0 |   | 0   0.0 0.0 1.0|   | 0 0 0 1.0 |

CIColorCube can probably reproduce more complex transformations, but the format of its data is complicated. You need to create a 3D lookup table.

CIToneCurve could do it if you did 3 separate passes (or maybe only 2 - one for both red and green and the 2nd one for only blue), and then combined the results. You'd set the 2nd point below 0.25 and the 4th point above 0.75 in red and green, and the opposite in blue.

Calomel answered 9/1, 2012 at 5:31 Comment(5)
I've tried so many ways to create the data for CIColorCube (#8538892). I was under the impression that a linear could not produce a split tone effect, but it does get close. Too bad CIToneCurve cannot do individual RGB channels. If you know how to create proper data for CIColorCube, let me know.Pattiepattin
Does chaining multiple CITones actually result in a change for each channel?Sorbitol
I don't think you could simply chain them together. I think you'd have to do each one separately and then pull the red, green, and blue channels from each one, and put them back together.Calomel
Chaining them does not seem to work from what I can tell. How would you pull the red, green, and blue channels and put them back together?Fess
You could apply the curve you want for red and green to an image and then run it through a color matrix with the blue channel (the 3rd row of the matrix) set to all 0s. Do the reverse for the blue channel - run the original image through the blue tone curve, and then through a color matrix where the red and green channels are all 0s. Then mix the 2 images together using the CIAdditionCompositing.Calomel
T
6

I got a very similar effect by first applying CIFalseImage. Pick your dark and light color (dark blue & red or orange). When you create the CIColor for the two colors, set the alpha to .5.

Next use CIScreenBlendMode and mix that filtered image with the orginal. It will look like a split tone.

It's a good hack to change shadows and highlights quickly.

CIFilter *lightDark = [CIFilter filterWithName:@"CIFalseColor"
                                       keysAndValues: @"inputImage", helper.ciImage, nil];
[lightDark setDefaults];
CIColor *myBlue = [CIColor colorWithRed:0.0 green:0.0 blue:0.6 alpha:0.5];
CIColor *myRed = [CIColor colorWithRed:1.0 green:0.8 blue:0.0 alpha:0.5];

[lightDark setValue:myBlue forKey:@"inputColor0"];
[lightDark setValue:myRed forKey:@"inputColor1"];
CIImage *mappedImage = [lightDark valueForKey:kCIOutputImageKey];

CIFilter *screenBlend = [CIFilter filterWithName:@"CIScreenBlendMode" keysAndValues: @"inputImage", mappedImage, @"inputBackgroundImage", helper.ciImage, nil];
CIImage *finalImage = [screenBlend valueForKey:kCIOutputImageKey];

if (finalImage) imageView.image = [UIImage imageWithCIImage:finalImage orientation:orientation];
else NSLog(@"Missing our image");
Tricycle answered 16/1, 2012 at 17:18 Comment(1)
Thanks, but as I mentioned I was looking for something that didn't require a blend composition. This was close to what I was using originally, though not with false color. Might look cool, I'll try it.Pattiepattin
C
3

I've been reading a little about how to do this in Photoshop, and it's basically increasing the contrast in the red and green channels and decreasing it in the blue channels. (At least for a basic effect - if you really do it with film, you can get some really odd color shifts, too!)

You can do contrast adjustment using a series of CIColorMatrix nodes. Contrast is basically ((value - 0.5) * contrast) + 0.5. So a color matrix for, say, a contrast of 1.5 in red and green, and 0.66 in blue, would be something like

| 1 0 0 -0.5 |   | 1.5 0.0 0    0 |   | 1 0 0 0.5 |
| 0 1 0 -0.5 | + | 0   1.5 0    0 | + | 0 1 0 0.5 |
| 0 0 1 -0.5 |   | 0   0.0 0.66 0 |   | 0 0 1 0.5 |
| 0 0 0  1.0 |   | 0   0.0 0.0 1.0|   | 0 0 0 1.0 |

CIColorCube can probably reproduce more complex transformations, but the format of its data is complicated. You need to create a 3D lookup table.

CIToneCurve could do it if you did 3 separate passes (or maybe only 2 - one for both red and green and the 2nd one for only blue), and then combined the results. You'd set the 2nd point below 0.25 and the 4th point above 0.75 in red and green, and the opposite in blue.

Calomel answered 9/1, 2012 at 5:31 Comment(5)
I've tried so many ways to create the data for CIColorCube (#8538892). I was under the impression that a linear could not produce a split tone effect, but it does get close. Too bad CIToneCurve cannot do individual RGB channels. If you know how to create proper data for CIColorCube, let me know.Pattiepattin
Does chaining multiple CITones actually result in a change for each channel?Sorbitol
I don't think you could simply chain them together. I think you'd have to do each one separately and then pull the red, green, and blue channels from each one, and put them back together.Calomel
Chaining them does not seem to work from what I can tell. How would you pull the red, green, and blue channels and put them back together?Fess
You could apply the curve you want for red and green to an image and then run it through a color matrix with the blue channel (the 3rd row of the matrix) set to all 0s. Do the reverse for the blue channel - run the original image through the blue tone curve, and then through a color matrix where the red and green channels are all 0s. Then mix the 2 images together using the CIAdditionCompositing.Calomel

© 2022 - 2024 — McMap. All rights reserved.