您的位置:首页 > 移动开发 > IOS开发

iOS中的图像处理(三)——混合运算

2016-01-21 16:24 459 查看
有时候,单独对一张图像进行处理是很难或者根本达不到我们想要的效果的。一个好的滤镜效果的诞生,往往要经过很多复杂步骤、细致微调、图片应用效果观察以及很多图层叠加。
我在JSWidget上发现了一些常用混合算法,对应着一些常用混合模式,通过这些blend
modes,我们可以指定两张图像如何混合。
不过在此之前,我们需要纯颜色图像和渐变图像来做辅助:

[cpp] view
plain copy

+ (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] view
plain copy

+ (UIImage *)imageWithGradient:(UIImage *)image startColor:(UIColor *)startColor endColor:(UIColor *)endColor

{

UIGraphicsBeginImageContextWithOptions(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;

}

而且在第一篇文章中提到的透明度滤镜(作用域像素的alpha值上)是没效果的,可以通过Quartz 2D来实现:

[cpp] view
plain copy

- (UIImage *)setAlpha:(CGFloat)alpha

{

// http://stackoverflow.com/questions/5084845/how-to-set-the-opacity-alpha-of-a-uiimage
UIGraphicsBeginImageContextWithOptions(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;

}

在此基础上,通过下面四行代码,可以分别得到四种不同效果:

[cpp] view
plain copy

return [[UIImage imageWithColor:[UIColor purpleColor] size:originImage.size] changeOpacityByFactor:0.5];;

[cpp] view
plain copy

return [UIImage imageWithGradient:originImage startColor:[UIColor whiteColor] endColor:[UIColor yellowColor]];

[cpp] view
plain copy

return [[originImage tintWithMaxRGBA:(RGBA){190, 190, 230} minRGBA:(RGBA){50, 35, 10}] overlayWithImage:[[UIImage imageWithColor:[UIColor purpleColor] size:originImage.size] changeOpacityByFactor:0.3]];

[cpp] view
plain copy

return [originImage softlightWithImage:[[UIImage imageWithColor:[UIColor yellowColor] size:originImage.size] changeOpacityByFactor:0.8]];









其中,overlay算法如下:

[cpp] view
plain copy

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));

}
内容来自用户分享和网络整理,不保证内容的准确性,如有侵权内容,可联系管理员处理 点击这里给我发消息
标签: