Iphone之选择图片滤镜功能的实现

来源:互联网 发布:dem地球软件 编辑:程序博客网 时间:2024/06/08 05:59

本文固定链接: http://www.zhouxiaodong.net/?p=66 | 忧郁小洞洞的站


Iphone之选择图片滤镜功能的实现

首先大家在做关于自拍软件的时候,会涉及到这样的功能,就是说给图片加滤镜,比如黑白,复古等效果,来使照片显示不同的效果。下面代码,就是如何实现了这一功能,当然,你可以加上你自己的效果,

个实现的效果如图:

photo2photo3

[cpp] view plaincopy
  1. #import <UIKit/UIKit.h>  
  2. #import <QuartzCore/QuartzCore.h>  
  3.    
  4. @interface PhotoSelectViewController : UIViewController  
  5. {  
  6.    
  7. IBOutlet UIImageView *imageView;//图片  
  8.    
  9. IBOutlet UIScrollView *scrollerView;//滚动视图显示所有滤镜图片  
  10.    
  11. UIImage *theImage;//原始图片  
  12.    
  13. int selectIndex;//选择的第几个图片  
  14. }  
  15. @end  


[cpp] view plaincopy
  1. /******各种颜色的设定*******/  
  2. //LOMO  
  3. const float colormatrix_lomo[] = {  
  4. 1.7f,  0.1f, 0.1f, 0, -73.1f,  
  5. 0,  1.7f, 0.1f, 0, -73.1f,  
  6. 0,  0.1f, 1.6f, 0, -73.1f,  
  7. 0,  0, 0, 1.0f, 0 };  
  8.    
  9. //黑白  
  10. const float colormatrix_heibai[] = {  
  11. 0.8f,  1.6f, 0.2f, 0, -163.9f,  
  12. 0.8f,  1.6f, 0.2f, 0, -163.9f,  
  13. 0.8f,  1.6f, 0.2f, 0, -163.9f,  
  14. 0,  0, 0, 1.0f, 0 };  
  15. //复古  
  16. const float colormatrix_huajiu[] = {  
  17. 0.2f,0.5f, 0.1f, 0, 40.8f,  
  18. 0.2f, 0.5f, 0.1f, 0, 40.8f,  
  19. 0.2f,0.5f, 0.1f, 0, 40.8f,  
  20. 0, 0, 0, 1, 0 };  
  21.    
  22. //哥特  
  23. const float colormatrix_gete[] = {  
  24. 1.9f,-0.3f, -0.2f, 0,-87.0f,  
  25. -0.2f, 1.7f, -0.1f, 0, -87.0f,  
  26. -0.1f,-0.6f, 2.0f, 0, -87.0f,  
  27. 0, 0, 0, 1.0f, 0 };  
  28.    
  29. //锐化  
  30. const float colormatrix_ruise[] = {  
  31. 4.8f,-1.0f, -0.1f, 0,-388.4f,  
  32. -0.5f,4.4f, -0.1f, 0,-388.4f,  
  33. -0.5f,-1.0f, 5.2f, 0,-388.4f,  
  34. 0, 0, 0, 1.0f, 0 };  
  35.    
  36. //淡雅  
  37. const float colormatrix_danya[] = {  
  38. 0.6f,0.3f, 0.1f, 0,73.3f,  
  39. 0.2f,0.7f, 0.1f, 0,73.3f,  
  40. 0.2f,0.3f, 0.4f, 0,73.3f,  
  41. 0, 0, 0, 1.0f, 0 };  
  42.    
  43. //酒红  
  44. const float colormatrix_jiuhong[] = {  
  45. 1.2f,0.0f, 0.0f, 0.0f,0.0f,  
  46. 0.0f,0.9f, 0.0f, 0.0f,0.0f,  
  47. 0.0f,0.0f, 0.8f, 0.0f,0.0f,  
  48. 0, 0, 0, 1.0f, 0 };  
  49.    
  50. //清宁  
  51. const float colormatrix_qingning[] = {  
  52. 0.9f, 0, 0, 0, 0,  
  53. 0, 1.1f,0, 0, 0,  
  54. 0, 0, 0.9f, 0, 0,  
  55. 0, 0, 0, 1.0f, 0 };  
  56.    
  57. //浪漫  
  58. const float colormatrix_langman[] = {  
  59. 0.9f, 0, 0, 0, 63.0f,  
  60. 0, 0.9f,0, 0, 63.0f,  
  61. 0, 0, 0.9f, 0, 63.0f,  
  62. 0, 0, 0, 1.0f, 0 };  
  63.    
  64. //光晕  
  65. const float colormatrix_guangyun[] = {  
  66. 0.9f, 0, 0,  0, 64.9f,  
  67. 0, 0.9f,0,  0, 64.9f,  
  68. 0, 0, 0.9f,  0, 64.9f,  
  69. 0, 0, 0, 1.0f, 0 };  
  70.    
  71. //蓝调  
  72. const float colormatrix_landiao[] = {  
  73. 2.1f, -1.4f, 0.6f, 0.0f, -31.0f,  
  74. -0.3f, 2.0f, -0.3f, 0.0f, -31.0f,  
  75. -1.1f, -0.2f, 2.6f, 0.0f, -31.0f,  
  76. 0.0f, 0.0f, 0.0f, 1.0f, 0.0f  
  77. };  
  78.    
  79. //梦幻  
  80. const float colormatrix_menghuan[] = {  
  81. 0.8f, 0.3f, 0.1f, 0.0f, 46.5f,  
  82. 0.1f, 0.9f, 0.0f, 0.0f, 46.5f,  
  83. 0.1f, 0.3f, 0.7f, 0.0f, 46.5f,  
  84. 0.0f, 0.0f, 0.0f, 1.0f, 0.0f  
  85. };  
  86.    
  87. //夜色  
  88. const float colormatrix_yese[] = {  
  89. 1.0f, 0.0f, 0.0f, 0.0f, -66.6f,  
  90. 0.0f, 1.1f, 0.0f, 0.0f, -66.6f,  
  91. 0.0f, 0.0f, 1.0f, 0.0f, -66.6f,  
  92. 0.0f, 0.0f, 0.0f, 1.0f, 0.0f  
  93. };  
  94.    
  95. #import "PhotoSelectViewController.h"  
  96.    
  97. @interface PhotoSelectViewController ()  
  98.    
  99. @end  
  100.    
  101. @implementation PhotoSelectViewController  
  102.    
  103. - (id)initWithNibName:(NSString *)nibNameOrNil bundle:(NSBundle *)nibBundleOrNil  
  104. {  
  105. self = [super initWithNibName:nibNameOrNil bundle:nibBundleOrNil];  
  106. if (self) {  
  107. // Custom initialization  
  108. }  
  109. return self;  
  110. }  
  111.    
  112. - (void)viewDidLoad  
  113. {  
  114. [super viewDidLoad];  
  115.    
  116. theImage = [UIImage imageNamed:@"photo.png"];  
  117. imageView.image = theImage;  
  118.    
  119. //添加滤镜  
  120. NSArray *arr = [NSArray arrayWithObjects:@"原图",@"LOMO",@"黑白",@"复古",@"哥特",@"锐色",@"淡雅",@"酒红",@"青柠",@"浪漫",@"光晕",@"蓝调",@"梦幻",@"夜色", nil];  
  121. //设置滚动视频的属性  
  122. scrollerView.backgroundColor = [UIColor colorWithRed:0 green:0 blue:0 alpha:0.5];  
  123. scrollerView.indicatorStyle = UIScrollViewIndicatorStyleBlack;  
  124. scrollerView.showsHorizontalScrollIndicator = NO;  
  125. scrollerView.showsVerticalScrollIndicator = NO;//关闭纵向滚动条  
  126. scrollerView.bounces = NO;  
  127.    
  128. //把所有的显示效果图添加到scrollerView里面  
  129. float x ;//计算x坐标  
  130. for(int i=0;i<arr.count;i++)  
  131. {  
  132. x = 5 + 51*i;  
  133. //添加点击手势识别,来处理选择的图片  
  134. UITapGestureRecognizer *recognizer = [[UITapGestureRecognizer alloc] initWithTarget:self action:@selector(setImageStyle:)];  
  135. recognizer.numberOfTouchesRequired = 1;  
  136. recognizer.numberOfTapsRequired = 1;  
  137.    
  138. //添加名字标签  
  139. UILabel *label = [[UILabel alloc] initWithFrame:CGRectMake(x, 53, 40, 23)];  
  140. [label setBackgroundColor:[UIColor clearColor]];  
  141. [label setText:[arr objectAtIndex:i]];  
  142. [label setTextAlignment:NSTextAlignmentCenter];  
  143. [label setFont:[UIFont systemFontOfSize:13.0f]];  
  144. [label setTextColor:[UIColor whiteColor]];  
  145. [label setUserInteractionEnabled:YES];  
  146. [label setTag:i];  
  147.    
  148. [scrollerView addSubview:label];  
  149.    
  150. //添加效果图片  
  151. int tag = i+1000;  
  152. UIImageView *bgImageView = [[UIImageView alloc]initWithFrame:CGRectMake(x, 10, 43, 43)];  
  153. [bgImageView setTag:tag];  
  154. [bgImageView addGestureRecognizer:recognizer];  
  155. [bgImageView setUserInteractionEnabled:YES];  
  156. UIImage *bgImage = [self changeImage:bgImageView.tag imageView:nil];  
  157. bgImageView.image = bgImage;  
  158. [scrollerView addSubview:bgImageView];  
  159. [bgImageView setBackgroundColor:[UIColor redColor]];  
  160.    
  161. //导入 <QuartzCore/QuartzCore.h>  
  162. //添加是否选中边框,选中时边框为黄色,默认是第一个被选中的  
  163. if (i == 0) {  
  164.    
  165. CALayer * layer = [bgImageView layer];  
  166. layer.borderColor = [[UIColor yellowColor] CGColor];  
  167. layer.borderWidth = 1.0f;  
  168.    
  169. selectIndex = tag;  
  170. }else{  
  171. CALayer * layer = [bgImageView layer];  
  172. layer.borderColor = [[UIColor blackColor] CGColor];  
  173. layer.borderWidth = 1.0f;  
  174. }  
  175.    
  176. }  
  177. //设置滚动视图的实际大小  
  178. scrollerView.contentSize = CGSizeMake(x + 55, 60);  
  179.    
  180. }  
  181. //选择图片处理方法  
  182. - (IBAction)setImageStyle:(UITapGestureRecognizer *)sender  
  183. {  
  184. //获取效果图  
  185. UIImage *image =   [self changeImage:sender.view.tag imageView:nil];  
  186.    
  187. if (selectIndex != sender.view.tag) {  
  188. //取消选择边框  
  189. UIImageView *noselectImageView = (UIImageView*)[self.view viewWithTag:selectIndex];  
  190. CALayer * nolayer = [noselectImageView layer];  
  191. nolayer.borderColor = [[UIColor blackColor] CGColor];  
  192. nolayer.borderWidth = 1.0f;  
  193.    
  194. selectIndex = sender.view.tag;  
  195. UIImageView *selectImageView = (UIImageView*)[self.view viewWithTag:selectIndex];  
  196. //添加选择边框  
  197. CALayer * layer = [selectImageView layer];  
  198. layer.borderColor = [[UIColor yellowColor] CGColor];  
  199. layer.borderWidth = 1.0f;  
  200. }  
  201.    
  202. //图片设置  
  203. [imageView setImage:image];  
  204. }  
  205.    
  206. //选择的效果图  
  207. -(UIImage *)changeImage:(int)index imageView:(UIImageView *)imageView  
  208. {  
  209. UIImage *image;  
  210.    
  211. switch (index-1000) {  
  212. case 0:  
  213. {  
  214. return theImage;  
  215. }  
  216. break;  
  217. case 1:  
  218. {  
  219. image = [self imageWithImage:theImage withColorMatrix:colormatrix_lomo];  
  220. }  
  221. break;  
  222. case 2:  
  223. {  
  224. image = [self imageWithImage:theImage withColorMatrix:colormatrix_heibai];  
  225. }  
  226. break;  
  227. case 3:  
  228. {  
  229. image = [self imageWithImage:theImage withColorMatrix:colormatrix_huajiu];  
  230. }  
  231. break;  
  232. case 4:  
  233. {  
  234. image = [self imageWithImage:theImage withColorMatrix:colormatrix_gete];  
  235. }  
  236. break;  
  237. case 5:  
  238. {  
  239. image = [self imageWithImage:theImage withColorMatrix:colormatrix_ruise];  
  240. }  
  241. break;  
  242. case 6:  
  243. {  
  244. image = [self imageWithImage:theImage withColorMatrix:colormatrix_danya];  
  245. }  
  246. break;  
  247. case 7:  
  248. {  
  249. image = [self imageWithImage:theImage withColorMatrix:colormatrix_jiuhong];  
  250. }  
  251. break;  
  252. case 8:  
  253. {  
  254. image = [self imageWithImage:theImage withColorMatrix:colormatrix_qingning];  
  255. }  
  256. break;  
  257. case 9:  
  258. {  
  259. image = [self imageWithImage:theImage withColorMatrix:colormatrix_langman];  
  260. }  
  261. break;  
  262. case 10:  
  263. {  
  264. image = [self imageWithImage:theImage withColorMatrix:colormatrix_guangyun];  
  265. }  
  266. break;  
  267. case 11:  
  268. {  
  269. image = [self imageWithImage:theImage withColorMatrix:colormatrix_landiao];  
  270.    
  271. }  
  272. break;  
  273. case 12:  
  274. {  
  275. image = [self imageWithImage:theImage withColorMatrix:colormatrix_menghuan];  
  276.    
  277. }  
  278. break;  
  279. case 13:  
  280. {  
  281. image = [self imageWithImage:theImage withColorMatrix:colormatrix_yese];  
  282.    
  283. }  
  284. }  
  285. return image;  
  286. }  
  287.    
  288. //效果图  
  289. -(UIImage*)imageWithImage:(UIImage*)inImage withColorMatrix:(const float*) f  
  290. {  
  291. unsigned char *imgPixel = RequestImagePixelData(inImage);  
  292. CGImageRef inImageRef = [inImage CGImage];  
  293. GLuint w = CGImageGetWidth(inImageRef);  
  294. GLuint h = CGImageGetHeight(inImageRef);  
  295.    
  296. int wOff = 0;  
  297. int pixOff = 0;  
  298.    
  299. for(GLuint y = 0;y< h;y++)//双层循环按照长宽的像素个数迭代每个像素点  
  300. {  
  301. pixOff = wOff;  
  302.    
  303. for (GLuint x = 0; x<w; x++)  
  304. {  
  305. int red = (unsigned char)imgPixel[pixOff];  
  306. int green = (unsigned char)imgPixel[pixOff+1];  
  307. int blue = (unsigned char)imgPixel[pixOff+2];  
  308. int alpha = (unsigned char)imgPixel[pixOff+3];  
  309. changeRGBA(&red, &green, &blue, &alpha, f);  
  310.    
  311. //回写数据  
  312. imgPixel[pixOff] = red;  
  313. imgPixel[pixOff+1] = green;  
  314. imgPixel[pixOff+2] = blue;  
  315. imgPixel[pixOff+3] = alpha;  
  316.    
  317. pixOff += 4; //将数组的索引指向下四个元素  
  318. }  
  319.    
  320. wOff += w * 4;  
  321. }  
  322.    
  323. NSInteger dataLength = w * h * 4;  
  324.    
  325. //下面的代码创建要输出的图像的相关参数  
  326. CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, imgPixel, dataLength, NULL);  
  327.    
  328. int bitsPerComponent = 8;  
  329. int bitsPerPixel = 32;  
  330. int bytesPerRow = 4 * w;  
  331. CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();  
  332. CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;  
  333. CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;  
  334.    
  335. CGImageRef imageRef = CGImageCreate(w, h, bitsPerComponent, bitsPerPixel, bytesPerRow,colorSpaceRef, bitmapInfo, provider, NULL, NO, renderingIntent);//创建要输出的图像  
  336.    
  337. UIImage *myImage = [UIImage imageWithCGImage:imageRef];  
  338.    
  339. CFRelease(imageRef);  
  340. CGColorSpaceRelease(colorSpaceRef);  
  341. CGDataProviderRelease(provider);  
  342. return myImage;  
  343. }  
  344.    
  345. static CGContextRef CreateRGBABitmapContext (CGImageRef inImage)// 返回一个使用RGBA通道的位图上下文  
  346. {  
  347. CGContextRef context = NULL;  
  348. CGColorSpaceRef colorSpace;  
  349. void *bitmapData; //内存空间的指针,该内存空间的大小等于图像使用RGB通道所占用的字节数。  
  350. int bitmapByteCount;  
  351. int bitmapBytesPerRow;  
  352.    
  353. size_t pixelsWide = CGImageGetWidth(inImage); //获取横向的像素点的个数  
  354. size_t pixelsHigh = CGImageGetHeight(inImage); //纵向  
  355.    
  356. bitmapBytesPerRow    = (pixelsWide * 4); //每一行的像素点占用的字节数,每个像素点的ARGB四个通道各占8个bit(0-255)的空间  
  357. bitmapByteCount    = (bitmapBytesPerRow * pixelsHigh); //计算整张图占用的字节数  
  358.    
  359. colorSpace = CGColorSpaceCreateDeviceRGB();//创建依赖于设备的RGB通道  
  360.    
  361. bitmapData = malloc(bitmapByteCount); //分配足够容纳图片字节数的内存空间  
  362.    
  363. context = CGBitmapContextCreate (bitmapData, pixelsWide, pixelsHigh, 8, bitmapBytesPerRow, colorSpace, kCGImageAlphaPremultipliedLast);  
  364. //创建CoreGraphic的图形上下文,该上下文描述了bitmaData指向的内存空间需要绘制的图像的一些绘制参数  
  365.    
  366. CGColorSpaceRelease( colorSpace );  
  367. //Core Foundation中通过含有Create、Alloc的方法名字创建的指针,需要使用CFRelease()函数释放  
  368.    
  369. return context;  
  370. }  
  371.    
  372. static unsigned char *RequestImagePixelData(UIImage *inImage)  
  373. // 返回一个指针,该指针指向一个数组,数组中的每四个元素都是图像上的一个像素点的RGBA的数值(0-255),用无符号的char是因为它正好的取值范围就是0-255  
  374. {  
  375. CGImageRef img = [inImage CGImage];  
  376. CGSize size = [inImage size];  
  377.    
  378. CGContextRef cgctx = CreateRGBABitmapContext(img); //使用上面的函数创建上下文  
  379.    
  380. CGRect rect = {{0,0},{size.width, size.height}};  
  381.    
  382. CGContextDrawImage(cgctx, rect, img); //将目标图像绘制到指定的上下文,实际为上下文内的bitmapData。  
  383. unsigned char *data = CGBitmapContextGetData (cgctx);  
  384.    
  385. CGContextRelease(cgctx);//释放上面的函数创建的上下文  
  386. return data;  
  387. }  
  388.    
  389. static void changeRGBA(int *red,int *green,int *blue,int *alpha, const float* f)//修改RGB的值  
  390. {  
  391. int redV = *red;  
  392. int greenV = *green;  
  393. int blueV = *blue;  
  394. int alphaV = *alpha;  
  395.    
  396. *red = f[0] * redV + f[1] * greenV + f[2] * blueV + f[3] * alphaV + f[4];  
  397. *green = f[0+5] * redV + f[1+5] * greenV + f[2+5] * blueV + f[3+5] * alphaV + f[4+5];  
  398. *blue = f[0+5*2] * redV + f[1+5*2] * greenV + f[2+5*2] * blueV + f[3+5*2] * alphaV + f[4+5*2];  
  399. *alpha = f[0+5*3] * redV + f[1+5*3] * greenV + f[2+5*3] * blueV + f[3+5*3] * alphaV + f[4+5*3];  
  400.    
  401. if (*red > 255)  
  402. {  
  403. *red = 255;  
  404. }  
  405. if(*red < 0)  
  406. {  
  407. *red = 0;  
  408. }  
  409. if (*green > 255)  
  410. {  
  411. *green = 255;  
  412. }  
  413. if (*green < 0)  
  414. {  
  415. *green = 0;  
  416. }  
  417. if (*blue > 255)  
  418. {  
  419. *blue = 255;  
  420. }  
  421. if (*blue < 0)  
  422. {  
  423. *blue = 0;  
  424. }  
  425. if (*alpha > 255)  
  426. {  
  427. *alpha = 255;  
  428. }  
  429. if (*alpha < 0)  
  430. {  
  431. *alpha = 0;  
  432. }  
  433. }  
  434.    
  435. - (void)didReceiveMemoryWarning  
  436. {  
  437. [super didReceiveMemoryWarning];  
  438. // Dispose of any resources that can be recreated.  
  439. }  
  440.    
  441. - (void)viewDidUnload {  
  442. imageView = nil;  
  443. scrollerView = nil;  
  444. [super viewDidUnload];  
  445. }  
  446. @end  

另注意,我用了xib,所以imageView和scrollView都是关联上的。

再附上一个自己拍的原图,大家来欣赏!


0 0
原创粉丝点击