最近在稍微做一些整理,翻起这部分的代码,发现是两个多月前的了。

这里讨论的是基于RGBA模型下的图像处理,即将变换作用在每个像素上。

代码是以UIImage的category形式存在的:

  1. typedef struct _singleRGBA
  2. {
  3. unsigned char red;
  4. unsigned char green;
  5. unsigned char blue;
  6. unsigned char alpha;
  7. } RGBA;
  8. @interface UIImage (ImageFilter)

首先,我们需要获得目标图像的位图信息;然后对每个像素进行变换;最后再生成图像。

  1. - (UIImage*)applyFilter:(FilterFunction)filter context:(void*)context
  2. {
  3. CGImageRef inImage = self.CGImage;
  4. CFDataRef m_DataRef = CGDataProviderCopyData(CGImageGetDataProvider(inImage));
  5. UInt8 *m_PixelBuf = (UInt8 *)CFDataGetBytePtr(m_DataRef);
  6. int length = CFDataGetLength(m_DataRef);
  7. for (int i=0; i<length; i+=4) {
  8. filter(m_PixelBuf, i, context);
  9. }
  10. CGContextRef ctx = CGBitmapContextCreate(m_PixelBuf,
  11. CGImageGetWidth(inImage),
  12. CGImageGetHeight(inImage),
  13. CGImageGetBitsPerComponent(inImage),
  14. CGImageGetBytesPerRow(inImage),
  15. CGImageGetColorSpace(inImage),
  16. CGImageGetBitmapInfo(inImage)
  17. );
  18. CGImageRef imageRef = CGBitmapContextCreateImage(ctx);
  19. CGContextRelease(ctx);
  20. UIImage *finalImage = [UIImage imageWithCGImage:imageRef];
  21. CGImageRelease(imageRef);
  22. CFRelease(m_DataRef);
  23. return finalImage;
  24. }

其中,FilterFunction声明如下:

  1. typedef void (*FilterFunction)(UInt8 *pixelBuf, UInt32 offset, void *context);

在此基础上,我们可以把每个变换操作独立出来,比如调整亮度、对比度、色调、透明度等:

  1. void filterOpacity(UInt8 *pixelBuf, UInt32 offset, void *context)
  2. {
  3. double val = *((double*)context);
  4. int a = offset+3;
  5. int alpha = pixelBuf[a];
  6. pixelBuf[a] = SAFECOLOR(alpha * val);
  7. }
  8. void filterBrightness(UInt8 *pixelBuf, UInt32 offset, void *context)
  9. {
  10. double t = *((double*)context);
  11. int r = offset;
  12. int g = offset+1;
  13. int b = offset+2;
  14. int red = pixelBuf[r];
  15. int green = pixelBuf[g];
  16. int blue = pixelBuf[b];
  17. pixelBuf[r] = SAFECOLOR(red * t);
  18. pixelBuf[g] = SAFECOLOR(green * t);
  19. pixelBuf[b] = SAFECOLOR(blue * t);
  20. }
  21. void filterSaturation(UInt8 *pixelBuf, UInt32 offset, void *context)
  22. {
  23. double t = *((double*)context); // t (- [0, 2]
  24. int r = offset;
  25. int g = offset+1;
  26. int b = offset+2;
  27. int red = pixelBuf[r];
  28. int green = pixelBuf[g];
  29. int blue = pixelBuf[b];
  30. red = red * (0.3086 * (1-t) + t) + green * (0.6094 * (1-t)) + blue * (0.0820 * (1-t));
  31. green = red * (0.3086 * (1-t)) + green * ((0.6094 * (1-t)) + t) + blue * (0.0820 * (1-t));
  32. blue = red * (0.3086 * (1-t)) + green * (0.6094 * (1-t)) + blue * ((0.0820 * (1-t)) + t);
  33. pixelBuf[r] = SAFECOLOR(red);
  34. pixelBuf[g] = SAFECOLOR(green);
  35. pixelBuf[b] = SAFECOLOR(blue);
  36. }
  37. void filterContrast(UInt8 *pixelBuf, UInt32 offset, void *context)
  38. {
  39. double t = *((double*)context); // t (- [0, 10]
  40. int r = offset;
  41. int g = offset+1;
  42. int b = offset+2;
  43. int red = pixelBuf[r];
  44. int green = pixelBuf[g];
  45. int blue = pixelBuf[b];
  46. red = red * t + 128 * (1-t);
  47. green = green * t + 128 * (1-t);
  48. blue = blue * t + 128 * (1-t);
  49. pixelBuf[r] = SAFECOLOR(red);
  50. pixelBuf[g] = SAFECOLOR(green);
  51. pixelBuf[b] = SAFECOLOR(blue);
  52. }
  53. void filterPosterize(UInt8 *pixelBuf, UInt32 offset, void *context)
  54. {
  55. double levels = *((double*)context);
  56. if (levels == 0) levels = 1; // avoid divide by zero
  57. int step = 255 / levels;
  58. int r = offset;
  59. int g = offset+1;
  60. int b = offset+2;
  61. int red = pixelBuf[r];
  62. int green = pixelBuf[g];
  63. int blue = pixelBuf[b];
  64. pixelBuf[r] = SAFECOLOR((red / step) * step);
  65. pixelBuf[g] = SAFECOLOR((green / step) * step);
  66. pixelBuf[b] = SAFECOLOR((blue / step) * step);
  67. }
  68. void filterDesaturate(UInt8 *pixelBuf, UInt32 offset, void *context)
  69. {
  70. int r = offset;
  71. int g = offset+1;
  72. int b = offset+2;
  73. int red = pixelBuf[r];
  74. int green = pixelBuf[g];
  75. int blue = pixelBuf[b];
  76. red = red * 0.3086 + green * 0.6094 + blue * 0.0820;
  77. green = red * 0.3086 + green * 0.6094 + blue * 0.0820;
  78. blue = red * 0.3086 + green * 0.6094 + blue * 0.0820;
  79. pixelBuf[r] = SAFECOLOR(red);
  80. pixelBuf[g] = SAFECOLOR(green);
  81. pixelBuf[b] = SAFECOLOR(blue);
  82. }
  83. void filterInvert(UInt8 *pixelBuf, UInt32 offset, void *context)
  84. {
  85. int r = offset;
  86. int g = offset+1;
  87. int b = offset+2;
  88. int red = pixelBuf[r];
  89. int green = pixelBuf[g];
  90. int blue = pixelBuf[b];
  91. pixelBuf[r] = SAFECOLOR(255-red);
  92. pixelBuf[g] = SAFECOLOR(255-green);
  93. pixelBuf[b] = SAFECOLOR(255-blue);
  94. }
  95. void filterTint(UInt8 *pixelBuf, UInt32 offset, void *context)
  96. {
  97. RGBA *rgbaArray = (RGBA*)context;
  98. RGBA maxRGBA = rgbaArray[0];
  99. RGBA minRGBA = rgbaArray[1];
  100. int r = offset;
  101. int g = offset+1;
  102. int b = offset+2;
  103. int red = pixelBuf[r];
  104. int green = pixelBuf[g];
  105. int blue = pixelBuf[b];
  106. pixelBuf[r] = SAFECOLOR((red - minRGBA.red) * (255.0 / (maxRGBA.red - minRGBA.red)));
  107. pixelBuf[g] = SAFECOLOR((green - minRGBA.green) * (255.0 / (maxRGBA.green - minRGBA.green)));
  108. pixelBuf[b] = SAFECOLOR((blue - minRGBA.blue) * (255.0 / (maxRGBA.blue - minRGBA.blue)));
  109. }

其中SAFECOLOR宏如下:

  1. #define SAFECOLOR(color) MIN(255,MAX(0,color))

最后,拿一张帅气的Andy照片来实践下,希望没有侵犯到肖像权。
原图如下:

通过以下四种变换,可以分别得到四张处理过的图片:

  1. return [originImage changeOpacityByFactor:0.5];
  1. return [originImage changeBrightnessByFactor:1.2];
  1. return [originImage changeSaturationByFactor:2.0];
  1. return [originImage tintWithMaxRGBA:(RGBA){190, 190, 230} minRGBA:(RGBA){50, 35, 10}];

 

 

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

iOS中的图像处理(一)——基础滤镜的更多相关文章

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

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

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

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

  3. iOS中数据库应用基础

    iOS 数据库入门 一.数据库简介 1.什么是数据库? 数据库(Database) 是按照数据结构来组织,存储和管理数据的仓库 数据库可以分为2大种类 关系型数据库(主流) PC端 Oracle My ...

  4. iOS 中的 HotFix 方案总结详解

    相信HotFix大家应该都很熟悉了,今天主要对于最近调研的一些方案做一些总结.iOS中的HotFix方案大致可以分为四种: WaxPatch(Alibaba) Dynamic Framework(Ap ...

  5. iOS中assign、copy 、retain等关键字的含义

    iOS中assign.copy .retain等关键字的含义  转自:http://my.oschina.net/majiage/blog/267409 assign: 简单赋值,不更改索引计数cop ...

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

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

  7. Cordoval在iOS中的运用整理

    一:关于Cordoval理论知识 1:PhoneGap是手机平台上流行的一款中间件.它构建在各种手机平台所提供的WebView(浏览器内核)组件的基础之上,使用javascript语言对应用开发者提供 ...

  8. iOS中集成ijkplayer视频直播框架

    ijkplayer 是一款做视频直播的框架, 基于ffmpeg, 支持 Android 和 iOS, 网上也有很多集成说明, 但是个人觉得还是不够详细, 在这里详细的讲一下在 iOS 中如何集成ijk ...

  9. iOS开发UI篇—Button基础

    iOS开发UI篇—Button基础 一.简单说明 一般情况下,点击某个控件后,会做出相应反应的都是按钮 按钮的功能比较多,既能显示文字,又能显示图片,还能随时调整内部图片和文字的位置 二.按钮的三种状 ...

随机推荐

  1. Webform中linq to sql多条件查询(小练习)

    多条件查询:逐条判断,从第一个条件开始判断,如果满足,取出放入集合,再从集合中查询第二个条件... aspx代码: <body> <form id="form1" ...

  2. JS图表组件 highcharts 简单的介绍

    把highcharts拿来做个简单的介绍,希望更多的朋友可以用到这个用来做图表的js插件. preparation Highcharts Highcharts是一个制作图表的纯Javascript类库 ...

  3. 【Cocos2D-x 3.5实战】坦克大战(2)游戏开始界面

    关于游戏的素材都是在网上到处搜集到的,然后自己再用二流的ps技术修修改改的,所以有可能混在一起有点不搭调(没有办法啊,没有美工Orz.. 项目已经建立好了,然后我们需要把我们下载的素材放到Resour ...

  4. BZOJ 2752: [HAOI2012]高速公路(road)( 线段树 )

    对于询问[L, R], 我们直接考虑每个p(L≤p≤R)的贡献,可以得到 然后化简一下得到 这样就可以很方便地用线段树, 维护一个p, p*vp, p*(p+1)*vp就可以了 ----------- ...

  5. Java学习之内部类

    示例1: package com.swust.面向对象; class Person1{ private String username="zhangsan"; public Per ...

  6. Java学习之对象实例化

    一个对象实例化过程:Person p = new Person();1,JVM会读取指定的路径下的Person.class文件,并加载进内存,并会先加载Person的父类(如果有直接的父类的情况下). ...

  7. jQuery 层级选择器 + keyCode

    层次选择器 如果想通过DOM元素之间的层次关系来获取特定的元素,例如后代元素,子元素,相邻元素和兄弟元素等,那么层次选择器是一个非常好的选择. 层次选择器规则如下: 层次选择器 选 择 器 描 述 返 ...

  8. DC游戏《斑鸠》原创赏析[转载]

    游戏背景:      凤来之国本来只是边远地区的一个小国.但现在他们却自称为得到“神之力”的“神通者”,在“选民思想”“和平统一”之类的名义下开始了对各地的武力侵略.      事情的起因是因为凤来之 ...

  9. 移动开发语言Swift

    苹果公布了全新的编程语言Swift,Swift继承了Objective-C语言特性,并从Python和Java Script中长处,使Swift更易读.未来swift编程语言的会特大广大的使用 Swi ...

  10. WinRT Toolkit 介绍--Control篇

    WinRT toolkit是组针对Windows Runtime XAML开发的一系列Control,extension和helper类.它和Windows Phone Toolkit一样,也是由很多 ...