iOS中的图像处理(三)——混合运算
有时候,单独对一张图像进行处理是很难或者根本达不到我们想要的效果的。一个好的滤镜效果的诞生,往往要经过很多复杂步骤、细致微调、图片应用效果观察以及很多图层叠加。
我在JSWidget上发现了一些常用混合算法,对应着一些常用混合模式,通过这些blend modes,我们可以指定两张图像如何混合。
不过在此之前,我们需要纯颜色图像和渐变图像来做辅助:
- + (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;
- }
- + (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来实现:
- - (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;
- }
在此基础上,通过下面四行代码,可以分别得到四种不同效果:
- return [[UIImage imageWithColor:[UIColor purpleColor] size:originImage.size] changeOpacityByFactor:0.5];;
- return [UIImage imageWithGradient:originImage startColor:[UIColor whiteColor] endColor:[UIColor yellowColor]];
- return [[originImage tintWithMaxRGBA:(RGBA){190, 190, 230} minRGBA:(RGBA){50, 35, 10}] overlayWithImage:[[UIImage imageWithColor:[UIColor purpleColor] size:originImage.size] changeOpacityByFactor:0.3]];
- return [originImage softlightWithImage:[[UIImage imageWithColor:[UIColor yellowColor] size:originImage.size] changeOpacityByFactor:0.8]];


其中,overlay算法如下:
- 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));
- }
版权声明:本文为博主原创文章,未经博主允许不得转载。
iOS中的图像处理(三)——混合运算的更多相关文章
- iOS中的图像处理(二)——卷积运算
关于图像处理中的卷积运算,这里有两份简明扼要的介绍:文一,文二. 其中,可能的一种卷积运算代码如下: - (UIImage*)applyConvolution:(NSArray*)kernel { C ...
- iOS中正则表达式的三种使用方式
1.利用NSPredicate(谓词)匹配 例如匹配有效邮箱: NSString *email = @“nijino_saki@163.com”: NSString *regex = @"[ ...
- iOS中的图像处理(一)——基础滤镜
最近在稍微做一些整理,翻起这部分的代码,发现是两个多月前的了. 这里讨论的是基于RGBA模型下的图像处理,即将变换作用在每个像素上. 代码是以UIImage的category形式存在的: typede ...
- iOS中几种常用的数据存储方式
自己稍微总结了一下下,方便大家查看 1.write直接写入文件的方法 永久保存在磁盘中,可以存储的对象有NSString.NSArray.NSDictionary.NSData.NSNumber,数据 ...
- [OpenCV-Python] OpenCV 中的图像处理 部分 IV (三)
部分 IVOpenCV 中的图像处理 OpenCV-Python 中文教程(搬运)目录 19 Canny 边缘检测 目标 • 了解 Canny 边缘检测的概念 • 学习函数 cv2.Canny() 1 ...
- Delphi中的三目运算函数有哪些?(XE10.2+WIN764)
相关资料:https://www.cnblogs.com/rogge7/p/6078903.html 问题现象:在做一个判断时突然想到了C++的三目运算,就在想Delphi中一共有几个? 问题处理: ...
- python中实现三目运算
python中没有其他语言中的三元表达式,不过有类似的实现方法 如: a = 1 b =2 k = 3 if a>b else 4 上面的代码就是python中实现三目运算的一个小demo, 如 ...
- 玩转iOS开发:iOS中的GCD开发(三)
上一章, 我们了解到了GCD里的一些队列和任务的知识, 也实践了一下, 同时我们也对主队列的一些小情况了解了一下, 比如上一章讲到的卡线程的问题, 如果没有看的朋友可以去看看玩转iOS开发:iOS中的 ...
- iOS中的几种锁的总结,三种开启多线程的方式(GCD、NSOperation、NSThread)
学习内容 欢迎关注我的iOS学习总结--每天学一点iOS:https://github.com/practiceqian/one-day-one-iOS-summary OC中的几种锁 为什么要引入锁 ...
随机推荐
- HTML静态网页的格式与布局(position:(fixed、absolute、relative)、分层、float(left、right))
一.position:fixed 锁定位置(相对于浏览器的位置),例如有些网站的右下角的弹出窗口. 示例: 二.position:absolute 1.外层没有position:absolute(或r ...
- HDU 2841 Visible Trees(莫比乌斯反演)
题目连接:http://acm.hdu.edu.cn/showproblem.php?pid=2841 题意:给n*m的矩阵(从(1,1)开始编号)格子,每个格子有一棵树,人站在(0,0)的位置,求可 ...
- BZOJ 1483: [HNOI2009]梦幻布丁( 链表 + 启发式合并 )
把相同颜色的串成一个链表, 然后每次A操作就启发式合并, 然后计算对答案的影响. ----------------------------------------------------------- ...
- HDU1171-Big Event in HDU
描述: Nowadays, we all know that Computer College is the biggest department in HDU. But, maybe you don ...
- html5 geolocation API
清单 1. 检查浏览器支持性if (navigator.geolocation) 清单 2. 单次定位请求 API void getCurrentPosition(updateLocation, op ...
- 5.6.1 Boolean类型
Boolean类型是与布尔值对应的引用类型.要创建Boolean对象,可以像下面这样调用Boolean构造函数并传入true或false值. var booleanObject=new Boolean ...
- centos6安装PHP5.4
安装的命令行很简单 sudo yum --enablerepo=remi install php 不过如果你没有配置源Repository,就需要首先启动REMI源: wget http://rpms ...
- C# DES加解密
加密 public static string Encrypt(string sourceString, string key, string iv) { try { byte[] btKey = E ...
- javascript closure 闭包 事件绑定
先来一个基本的例子 <!-- 实现一段脚本,使得点击对应链接alert出相应的编号 --> <meta http-equiv="Content-Type" con ...
- python下读取excel文件
项目中要用到这个,所以记录一下. python下读取excel文件方法多种,用的是普通的xlrd插件,因为它各种版本的excel文件都可读. 首先在https://pypi.python.org/py ...