有时候,单独对一张图像进行处理是很难或者根本达不到我们想要的效果的。一个好的滤镜效果的诞生,往往要经过很多复杂步骤、细致微调、图片应用效果观察以及很多图层叠加。

我在JSWidget上发现了一些常用混合算法,对应着一些常用混合模式,通过这些blend modes,我们可以指定两张图像如何混合。

不过在此之前,我们需要纯颜色图像和渐变图像来做辅助:

  1. + (UIImage *)imageWithColor:(UIColor *)color size:(CGSize)size
  2. {
  3. // http://stackoverflow.com/questions/1213790/how-to-get-a-color-image-in-iphone-sdk
  4. //Create a context of the appropriate size
  5. UIGraphicsBeginImageContext(size);
  6. CGContextRef currentContext = UIGraphicsGetCurrentContext();
  7. //Build a rect of appropriate size at origin 0,0
  8. CGRect fillRect = CGRectMake(0, 0, size.width, size.height);
  9. //Set the fill color
  10. CGContextSetFillColorWithColor(currentContext, color.CGColor);
  11. //Fill the color
  12. CGContextFillRect(currentContext, fillRect);
  13. //Snap the picture and close the context
  14. UIImage *colorImage = UIGraphicsGetImageFromCurrentImageContext();
  15. UIGraphicsEndImageContext();
  16. return colorImage;
  17. }
  1. + (UIImage *)imageWithGradient:(UIImage *)image startColor:(UIColor *)startColor endColor:(UIColor *)endColor
  2. {
  3. UIGraphicsBeginImageContextWithOptions(image.size, NO, image.scale);
  4. CGContextRef context = UIGraphicsGetCurrentContext();
  5. CGContextTranslateCTM(context, 0, image.size.height);
  6. CGContextScaleCTM(context, 1.0, -1.0);
  7. CGContextSetBlendMode(context, kCGBlendModeNormal);
  8. CGRect rect = CGRectMake(0, 0, image.size.width, image.size.height);
  9. CGContextDrawImage(context, rect, image.CGImage);
  10. // Create gradient
  11. NSArray *colors = [NSArray arrayWithObjects:(id)endColor.CGColor, (id)startColor.CGColor, nil];
  12. CGColorSpaceRef space = CGColorSpaceCreateDeviceRGB();
  13. CGGradientRef gradient = CGGradientCreateWithColors(space, (CFArrayRef)colors, NULL);
  14. // Apply gradient
  15. CGContextClipToMask(context, rect, image.CGImage);
  16. CGContextDrawLinearGradient(context, gradient, CGPointMake(0,0), CGPointMake(0, image.size.height), 0);
  17. UIImage *gradientImage = UIGraphicsGetImageFromCurrentImageContext();
  18. UIGraphicsEndImageContext();
  19. CGGradientRelease(gradient);
  20. CGColorSpaceRelease(space);
  21. return gradientImage;
  22. }

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

  1. - (UIImage *)setAlpha:(CGFloat)alpha
  2. {
  3. // http://stackoverflow.com/questions/5084845/how-to-set-the-opacity-alpha-of-a-uiimage
  4. UIGraphicsBeginImageContextWithOptions(self.size, NO, 0.0f);
  5. CGContextRef ctx = UIGraphicsGetCurrentContext();
  6. CGRect area = CGRectMake(0, 0, self.size.width, self.size.height);
  7. CGContextScaleCTM(ctx, 1, -1);
  8. CGContextTranslateCTM(ctx, 0, -area.size.height);
  9. CGContextSetBlendMode(ctx, kCGBlendModeMultiply);
  10. CGContextSetAlpha(ctx, alpha);
  11. CGContextDrawImage(ctx, area, self.CGImage);
  12. UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
  13. UIGraphicsEndImageContext();
  14. return newImage;
  15. }

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

  1. return [[UIImage imageWithColor:[UIColor purpleColor] size:originImage.size] changeOpacityByFactor:0.5];;
  1. return [UIImage imageWithGradient:originImage startColor:[UIColor whiteColor] endColor:[UIColor yellowColor]];
  1. return [[originImage tintWithMaxRGBA:(RGBA){190, 190, 230} minRGBA:(RGBA){50, 35, 10}] overlayWithImage:[[UIImage imageWithColor:[UIColor purpleColor] size:originImage.size] changeOpacityByFactor:0.3]];
  1. return [originImage softlightWithImage:[[UIImage imageWithColor:[UIColor yellowColor] size:originImage.size] changeOpacityByFactor:0.8]];

 

 

其中,overlay算法如下:

  1. double calcOverlay(float b, float t)
  2. {
  3. return (b > 128.0f) ? 255.0f - 2.0f * (255.0f - t) * (255.0f - b) / 255.0f: (b * t * 2.0f) / 255.0f;
  4. }
  5. void filterOverlay(UInt8 *pixelBuf, UInt8 *pixedBlendBuf, UInt32 offset, void *context)
  6. {
  7. int r = offset;
  8. int g = offset+1;
  9. int b = offset+2;
  10. int red = pixelBuf[r];
  11. int green = pixelBuf[g];
  12. int blue = pixelBuf[b];
  13. int blendRed = pixedBlendBuf[r];
  14. int blendGreen = pixedBlendBuf[g];
  15. int blendBlue = pixedBlendBuf[b];
  16. pixelBuf[r] = SAFECOLOR(calcOverlay(red, blendRed));
  17. pixelBuf[g] = SAFECOLOR(calcOverlay(green, blendGreen));
  18. pixelBuf[b] = SAFECOLOR(calcOverlay(blue, blendBlue));
  19. }

版权声明:本文为博主原创文章,未经博主允许不得转载。

iOS中的图像处理(三)——混合运算的更多相关文章

  1. iOS中的图像处理(二)——卷积运算

    关于图像处理中的卷积运算,这里有两份简明扼要的介绍:文一,文二. 其中,可能的一种卷积运算代码如下: - (UIImage*)applyConvolution:(NSArray*)kernel { C ...

  2. iOS中正则表达式的三种使用方式

    1.利用NSPredicate(谓词)匹配 例如匹配有效邮箱: NSString *email = @“nijino_saki@163.com”: NSString *regex = @"[ ...

  3. iOS中的图像处理(一)——基础滤镜

    最近在稍微做一些整理,翻起这部分的代码,发现是两个多月前的了. 这里讨论的是基于RGBA模型下的图像处理,即将变换作用在每个像素上. 代码是以UIImage的category形式存在的: typede ...

  4. iOS中几种常用的数据存储方式

    自己稍微总结了一下下,方便大家查看 1.write直接写入文件的方法 永久保存在磁盘中,可以存储的对象有NSString.NSArray.NSDictionary.NSData.NSNumber,数据 ...

  5. [OpenCV-Python] OpenCV 中的图像处理 部分 IV (三)

    部分 IVOpenCV 中的图像处理 OpenCV-Python 中文教程(搬运)目录 19 Canny 边缘检测 目标 • 了解 Canny 边缘检测的概念 • 学习函数 cv2.Canny() 1 ...

  6. Delphi中的三目运算函数有哪些?(XE10.2+WIN764)

    相关资料:https://www.cnblogs.com/rogge7/p/6078903.html 问题现象:在做一个判断时突然想到了C++的三目运算,就在想Delphi中一共有几个? 问题处理: ...

  7. python中实现三目运算

    python中没有其他语言中的三元表达式,不过有类似的实现方法 如: a = 1 b =2 k = 3 if a>b else 4 上面的代码就是python中实现三目运算的一个小demo, 如 ...

  8. 玩转iOS开发:iOS中的GCD开发(三)

    上一章, 我们了解到了GCD里的一些队列和任务的知识, 也实践了一下, 同时我们也对主队列的一些小情况了解了一下, 比如上一章讲到的卡线程的问题, 如果没有看的朋友可以去看看玩转iOS开发:iOS中的 ...

  9. iOS中的几种锁的总结,三种开启多线程的方式(GCD、NSOperation、NSThread)

    学习内容 欢迎关注我的iOS学习总结--每天学一点iOS:https://github.com/practiceqian/one-day-one-iOS-summary OC中的几种锁 为什么要引入锁 ...

随机推荐

  1. ssh环境搭建并实现登录功能

    参照了这篇博客,但是里面有些地方进行了更改 http://wenku.baidu.com/link?url=edeegTquV2eR3CJ5-zvNcJbyuq11Afp-lD2Fz2jfmuHhV1 ...

  2. 1.1. chromium源代码分析 - chromiumframe - 介绍

    本人能力有效,面对chromium庞大的代码就头大.还是先由前辈的chromiumFrame入手. 1. chromeFrame概貌 chromiumFrame是前辈的心血之作,以最小化的方式抽出ch ...

  3. BZOJ 1257 余数之和sum(分块优化)

    题目链接:http://acm.hust.edu.cn/vjudge/problem/viewProblem.action?id=46954 题意:f(n, k)=k mod 1 + k mod 2 ...

  4. 5.4.3 RegExp构造函数属性

    RegExp构造函数包含一些属性(这些属性在其他语言中被看成是静态属性).这些属性适用于作用域中的所有正则表达式,并且基于所执行的最近一次正则表达式操作而变化.关于这些属性的另一个独特之处,就是可以通 ...

  5. XCode里遇到 #include <XXX.h>file not found的解决方案

    最近在学习如何在C++里调用Java方法,遇到提示 #include <XXX.h> file  not  found 的问题.也google了好久都没有找到合适的解决方案. 认真的研究了 ...

  6. php制作数据字典

    /** * 生成mysql数据字典 */ header("Content-type:text/html;charset=utf-8"); // 配置数据库 $database = ...

  7. django分页linaro-django-pagination

    1.安装linaro-django-pagination settings INSTALLED_APPS = ( # ... 'linaro_django_pagination', ) MIDDLEW ...

  8. Sicily-1443

    一.      题意: 模拟队列的操作,按优先级pop.如果有元素pop,则其他在队列里面的元素的时间都要加1.如果队头的元素因为优先级不够高而要push回队列的时候,所有元素的时间都不用改变. 二. ...

  9. 不重新编译PHP文件的情况下php GD库扩展库的编译安装(centos)

    gd-2.0.33.tar.gz http://www.boutell.com/gd/ jpegsrc.v6b.tar.gz http://www.ijg.org/ libpng-1.2.7.tar. ...

  10. Andriod之Activity

    eclipse还原默认的面板设计:Window > Reset Perspective> OK1\ 1.多个Activity之间的关系: 2.Intent的基本作用: 3.在一个Activ ...