Sometimes it is difficult or impossible to process an image independently. The emergence of a good filter effect often requires a lot of complex steps, careful fine-tuning, image application effect observation, and many layers.
I found some common mixed algorithms on JSWidget, corresponding to some common mixed modes. Through these blend modes, we can specify how the two images are mixed.
However, before that, we need pure color images and gradient images for assistance:
[Cpp]
+ (UIImage *) imageWithColor :( UIColor *) color size :( CGSize) size
{
// Http://stackoverflow.com/questions/1213790/how-to-get-a-color-image-in-iphone-sdk
// Create a context of the appropriate size
UIGraphicsBeginImageContext (size );
CGContextRef currentContext = UIGraphicsGetCurrentContext ();
// Build a rect of appropriate size at origin 0, 0
CGRect fillRect = CGRectMake (0, 0, size. width, size. height );
// Set the fill color
CGContextSetFillColorWithColor (currentContext, color. CGColor );
// Fill the color
CGContextFillRect (currentContext, fillRect );
// Snap the picture and close the context
UIImage * colorImage = UIGraphicsGetImageFromCurrentImageContext ();
UIGraphicsEndImageContext ();
Return colorImage;
}
[Cpp]
+ (UIImage *) imageWithGradient :( UIImage *) image startColor :( UIColor *) startColor endColor :( UIColor *) endColor
{
Uigraphicsbeginimagecontextwitexceptions (image. size, NO, image. scale );
CGContextRef context = UIGraphicsGetCurrentContext ();
CGContextTranslateCTM (context, 0, image. size. height );
CGContextScaleCTM (context, 1.0,-1.0 );
CGContextSetBlendMode (context, kCGBlendModeNormal );
CGRect rect = CGRectMake (0, 0, image. size. width, image. size. height );
CGContextDrawImage (context, rect, image. CGImage );
// Create gradient
NSArray * colors = [NSArray arrayWithObjects :( id) endColor. CGColor, (id) startColor. CGColor, nil];
CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB ();
CGGradientRef gradient = CGGradientCreateWithColors (space, (CFArrayRef) colors, NULL );
// Apply gradient
CGContextClipToMask (context, rect, image. CGImage );
CGContextDrawLinearGradient (context, gradient, CGPointMake (0, 0), CGPointMake (0, image. size. height), 0 );
UIImage * gradientImage = UIGraphicsGetImageFromCurrentImageContext ();
UIGraphicsEndImageContext ();
CGGradientRelease (gradient );
CGColorSpaceRelease (space );
Return gradientImage;
}
In addition, the transparency filter mentioned in the first article (the alpha value of the scope pixel) is ineffective. It can be achieved through Quartz 2D:
[Cpp]
-(UIImage *) setAlpha :( CGFloat) alpha
{
// Http://stackoverflow.com/questions/5084845/how-to-set-the-opacity-alpha-of-a-uiimage
Uigraphicsbeginimagecontextwitexceptions (self. size, NO, 0.0f );
CGContextRef ctx = UIGraphicsGetCurrentContext ();
CGRect area = CGRectMake (0, 0, self. size. width, self. size. height );
CGContextScaleCTM (ctx, 1,-1 );
CGContextTranslateCTM (ctx, 0,-area. size. height );
CGContextSetBlendMode (ctx, kCGBlendModeMultiply );
CGContextSetAlpha (ctx, alpha );
CGContextDrawImage (ctx, area, self. CGImage );
UIImage * newImage = UIGraphicsGetImageFromCurrentImageContext ();
UIGraphicsEndImageContext ();
Return newImage;
}
On this basis, the following four lines of code can be used to obtain four different effects:
[Cpp]
Return [[UIImage imageWithColor: [UIColor purpleColor] size: originImage. size] changeOpacityByFactor: 0.5];
[Cpp]
Return [UIImage imageWithGradient: originImage startColor: [UIColor whiteColor] endColor: [UIColor yellowColor];
[Cpp]
Return [[originImage tintWithMaxRGBA :( RGBA) {190,190,230} minRGBA :( RGBA) {50, 35, 10}] overlayWithImage: [[UIImage imageWithColor: [UIColor purpleColor] size: originImage. size] changeOpacityByFactor: 0.3];
[Cpp]
Return [originImage softlightWithImage: [[UIImage imageWithColor: [UIColor yellowColor] size: originImage. size] changeOpacityByFactor: 0.8];
The overlay algorithm is as follows:
[Cpp]
Double calcOverlay (float B, float t)
{
Return (B> 128.0f )? 255.0f-2.0f * (255.0f-t) * (255.0f-B)/255.0f: (B * t * 2.0f)/255.0f;
}
Void filterOverlay (UInt8 * pixelBuf, UInt8 * pixedBlendBuf, UInt32 offset, void * context)
{
Int r = offset;
Int g = offset + 1;
Int B = offset + 2;
Int red = pixelBuf [r];
Int green = pixelBuf [g];
Int blue = pixelBuf [B];
Int blendRed = pixedBlendBuf [r];
Int blendGreen = pixedBlendBuf [g];
Int blendBlue = pixedBlendBuf [B];
PixelBuf [r] = SAFECOLOR (calcOverlay (red, blendRed ));
PixelBuf [g] = SAFECOLOR (calcOverlay (green, blendGreen ));
PixelBuf [B] = SAFECOLOR (calcOverlay (blue, blendBlue ));
}