ios 滤镜

来源:互联网 发布:淘宝 自带 库存管理 编辑:程序博客网 时间:2024/05/16 05:11

首先需要了解一下滤镜的原理:“用Core Graphic的API,把图片解析成RGBA四通道的位图放入内存,然后内存中有一个数组,数组中的每四个元素都是图像上的一个像素点的RGBA的数值(0-255),你只要改变RGB的数值,再写回去重新生成就可以了。简单的变化RGB很好改的,变为黑白照片就是把每个像素点的RGB的值相加求平均值,再回写回去。例如:R=B=G=100,就是灰色的,你只要写个for循环,把每个像素点的RGB都改成各自的平均值,照片就变为黑白色了。如果图像变为怀旧照片,就是底色发黄的,就是RG的比值调高,B保持不变,因为红绿相配就是黄色。”

第一步打开位图的像素数组

[html] view plain copy
  1. // 返回一个使用RGBA通道的位图上下文  
  2. static CGContextRef CreateRGBABitmapContext (CGImageRef inImage)  
  3. {  
  4.     CGContextRef context = NULL;  
  5.     CGColorSpaceRef colorSpace;  
  6.     void *bitmapData; //内存空间的指针,该内存空间的大小等于图像使用RGB通道所占用的字节数。  
  7.     int bitmapByteCount;  
  8.     int bitmapBytesPerRow;  
  9.       
  10.     size_t pixelsWide = CGImageGetWidth(inImage); //获取横向的像素点的个数  
  11.     size_t pixelsHigh = CGImageGetHeight(inImage);  
  12.       
  13.     bitmapBytesPerRow   = (pixelsWide * 4); //每一行的像素点占用的字节数,每个像素点的ARGB四个通道各占8个bit(0-255)的空间  
  14.     bitmapByteCount = (bitmapBytesPerRow * pixelsHigh); //计算整张图占用的字节数  
  15.       
  16.     colorSpace = CGColorSpaceCreateDeviceRGB();//创建依赖于设备的RGB通道  
  17.     //分配足够容纳图片字节数的内存空间  
  18.     bitmapData = malloc( bitmapByteCount );  
  19.     //创建CoreGraphic的图形上下文,该上下文描述了bitmaData指向的内存空间需要绘制的图像的一些绘制参数  
  20.     context = CGBitmapContextCreate (bitmapData,  
  21.                                      pixelsWide,  
  22.                                      pixelsHigh,  
  23.                                      8,  
  24.                                      bitmapBytesPerRow,  
  25.                                      colorSpace,  
  26.                                      kCGImageAlphaPremultipliedLast);  
  27.     //Core Foundation中通过含有Create、Alloc的方法名字创建的指针,需要使用CFRelease()函数释放  
  28.     CGColorSpaceRelease( colorSpace );  
  29.     return context;  
  30. }  

[html] view plain copy
  1. // 返回一个指针,该指针指向一个数组,数组中的每四个元素都是图像上的一个像素点的RGBA的数值(0-255),用无符号的char是因为它正好的取值范围就是0-255  
  2. static unsigned char *RequestImagePixelData(UIImage *inImage)  
  3. {  
  4.     CGImageRef img = [inImage CGImage];  
  5.     CGSize size = [inImage size];  
  6.     //使用上面的函数创建上下文  
  7.     CGContextRef cgctx = CreateRGBABitmapContext(img);  
  8.       
  9.     CGRect rect = {{0,0},{size.width, size.height}};  
  10.     //将目标图像绘制到指定的上下文,实际为上下文内的bitmapData。  
  11.     CGContextDrawImage(cgctx, rect, img);  
  12.     unsigned char *data = CGBitmapContextGetData (cgctx);  
  13.     //释放上面的函数创建的上下文  
  14.     CGContextRelease(cgctx);  
  15.     return data;  
  16. }  

获得以像素为单位的长和宽,开始处理位图中每个像素的值,生成指定效果

[html] view plain copy
  1. CGImageRef inImageRef = [inImage CGImage];  
  2.                 GLuint w = CGImageGetWidth(inImageRef);  
  3.                 GLuint h = CGImageGetHeight(inImageRef);  
  4.                   
  5.                 int wOff = 0;  
  6.                 int pixOff = 0;  
  7.                   
  8.                 //双层循环按照长宽的像素个数迭代每个像素点  
  9.                 for(GLuint y = 0;y< h;y++)  
  10.                 {  
  11.                     pixOff = wOff;  
  12.                       
  13.                     for (GLuint x = 0; x<w; x++)  
  14.                     {  
  15.                         int red = (unsigned char)imgPixel[pixOff];  
  16.                         int green = (unsigned char)imgPixel[pixOff+1];  
  17.                         int blue = (unsigned char)imgPixel[pixOff+2];  
  18.                         int alpha=(unsigned char)imgPixel[pixOff+3];  
  19.                         //NSLog(@"1------r=%d,g=%d,b=%d,a=%d,",red,green,blue,alpha);  
  20.                         changeRGBA(&red, &green, &blue, &alpha, f);  
  21.                         //NSLog(@"2------r=%d,g=%d,b=%d,a=%d,",red,green,blue,alpha);  
  22.                         //NSLog(@"--------------------------------------");  
  23.                         //回写数据  
  24.                         imgPixel[pixOff] = red;  
  25.                         imgPixel[pixOff+1] = green;  
  26.                         imgPixel[pixOff+2] = blue;  
  27.                         imgPixel[pixOff+3] = alpha;  
  28.                           
  29.                         //将数组的索引指向下四个元素  
  30.                         pixOff += 4;  
  31.                     }  
  32.                     wOff += w * 4;  
  33.                 }  
  34.                   
  35.                 NSInteger dataLength = w*h* 4;  

创建生成image所需的参数

[html] view plain copy
  1. //下面的代码创建要输出的图像的相关参数  
  2.                 CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, imgPixel, dataLength, NULL);  
  3.                 if (!provider) {  
  4.                     failedBlock(@"创建输出图像的相关参数失败!");  
  5.                 }else{  
  6.                     // prep the ingredients  
  7.                     int bitsPerComponent = 8;  
  8.                     int bitsPerPixel = 32;  
  9.                     int bytesPerRow = 4 * w;  
  10.                     CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();  
  11.                     CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;  
  12.                     CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;  
  13.                       
  14.                     //创建要输出的图像  
  15.                     CGImageRef imageRef = CGImageCreate(w, h,  
  16.                                                         bitsPerComponent,  
  17.                                                         bitsPerPixel,  
  18.                                                         bytesPerRow,  
  19.                                                         colorSpaceRef,  
  20.                                                         bitmapInfo,  
  21.                                                         provider,  
  22.                                                         NULL, NO, renderingIntent);  
  23.                     if (!imageRef) {  
  24.                         failedBlock(@"创建输出图像失败!");  
  25.                     }else{  
  26.                         UIImage *my_Image = [UIImage imageWithCGImage:imageRef];  
  27.                           
  28.                         CFRelease(imageRef);  
  29.                         CGColorSpaceRelease(colorSpaceRef);  
  30.                         CGDataProviderRelease(provider);  
  31.                           
  32.                         succeedBlock(my_Image);  
  33.                     }  

下面附上几组原作者李海峰写的颜色矩阵的数值

[html] view plain copy
  1. //ColorMatrix From Android  
  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. //淡雅  
  38. const float colormatrix_danya[] = {   
  39.     0.6f,0.3f, 0.1f, 0,73.3f,  
  40.     0.2f,0.7f, 0.1f, 0,73.3f,   
  41.     0.2f,0.3f, 0.4f, 0,73.3f,  
  42.     0, 0, 0, 1.0f, 0 };  
  43.   
  44. //酒红  
  45. const float colormatrix_jiuhong[] = {   
  46.     1.2f,0.0f, 0.0f, 0.0f,0.0f,  
  47.     0.0f,0.9f, 0.0f, 0.0f,0.0f,   
  48.     0.0f,0.0f, 0.8f, 0.0f,0.0f,  
  49.     0, 0, 0, 1.0f, 0 };  
  50.   
  51. //清宁  
  52. const float colormatrix_qingning[] = {   
  53.     0.9f, 0, 0, 0, 0,   
  54.     0, 1.1f,0, 0, 0,   
  55.     0, 0, 0.9f, 0, 0,   
  56.     0, 0, 0, 1.0f, 0 };  
  57.   
  58. //浪漫  
  59. const float colormatrix_langman[] = {   
  60.     0.9f, 0, 0, 0, 63.0f,   
  61.     0, 0.9f,0, 0, 63.0f,   
  62.     0, 0, 0.9f, 0, 63.0f,   
  63.     0, 0, 0, 1.0f, 0 };  
  64.   
  65. //光晕  
  66. const float colormatrix_guangyun[] = {   
  67.     0.9f, 0, 0,  0, 64.9f,  
  68.     0, 0.9f,0,  0, 64.9f,  
  69.     0, 0, 0.9f,  0, 64.9f,  
  70.     0, 0, 0, 1.0f, 0 };  
  71.   
  72. //蓝调  
  73. const float colormatrix_landiao[] = {  
  74.     2.1f, -1.4f, 0.6f, 0.0f, -31.0f,   
  75.     -0.3f, 2.0f, -0.3f, 0.0f, -31.0f,  
  76.     -1.1f, -0.2f, 2.6f, 0.0f, -31.0f,   
  77.     0.0f, 0.0f, 0.0f, 1.0f, 0.0f  
  78. };  
  79.   
  80. //梦幻  
  81. const float colormatrix_menghuan[] = {  
  82.     0.8f, 0.3f, 0.1f, 0.0f, 46.5f,   
  83.     0.1f, 0.9f, 0.0f, 0.0f, 46.5f,   
  84.     0.1f, 0.3f, 0.7f, 0.0f, 46.5f,   
  85.     0.0f, 0.0f, 0.0f, 1.0f, 0.0f  
  86. };  
  87.   
  88. //夜色  
  89. const float colormatrix_yese[] = {  
  90.     1.0f, 0.0f, 0.0f, 0.0f, -66.6f,  
  91.     0.0f, 1.1f, 0.0f, 0.0f, -66.6f,   
  92.     0.0f, 0.0f, 1.0f, 0.0f, -66.6f,   
  93.     0.0f, 0.0f, 0.0f, 1.0f, 0.0f  
  94. };  
0 0