iOS滤镜

<span style="font-size:24px;">今天重新看了一个巨人李海峰写的滤镜demo感觉非常的清晰易懂。
首先需要了解一下滤镜的原理:“用Core Graphic的API,把图片解析成RGBA四通道的位图放入内存,然后内存中有一个数组,数组中的每四个元素都是图像上的一个像素点的RGBA的数值(0-255),你只要改变RGB的数值,再写回去重新生成就可以了。简单的变化RGB很好改的,变为黑白照片就是把每个像素点的RGB的值相加求平均值,再回写回去。例如:R=B=G=100,就是灰色的,你只要写个for循环,把每个像素点的RGB都改成各自的平均值,照片就变为黑白色了。如果图像变为怀旧照片,就是底色发黄的,就是RG的比值调高,B保持不变,因为红绿相配就是黄色。”
第一步打开位图的像素数组
[html] view plaincopy
// 返回一个使用RGBA通道的位图上下文  
static CGContextRef CreateRGBABitmapContext (CGImageRef inImage)  
{  
    CGContextRef context = NULL;  
    CGColorSpaceRef colorSpace;  
    void *bitmapData; //内存空间的指针,该内存空间的大小等于图像使用RGB通道所占用的字节数。  
    int bitmapByteCount;  
    int bitmapBytesPerRow;  
      
    size_t pixelsWide = CGImageGetWidth(inImage); //获取横向的像素点的个数  
    size_t pixelsHigh = CGImageGetHeight(inImage);  
      
    bitmapBytesPerRow   = (pixelsWide * 4); //每一行的像素点占用的字节数,每个像素点的ARGB四个通道各占8个bit(0-255)的空间  
    bitmapByteCount = (bitmapBytesPerRow * pixelsHigh); //计算整张图占用的字节数  
      
    colorSpace = CGColorSpaceCreateDeviceRGB();//创建依赖于设备的RGB通道  
    //分配足够容纳图片字节数的内存空间  
    bitmapData = malloc( bitmapByteCount );  
    //创建CoreGraphic的图形上下文,该上下文描述了bitmaData指向的内存空间需要绘制的图像的一些绘制参数  
    context = CGBitmapContextCreate (bitmapData,  
                                     pixelsWide,  
                                     pixelsHigh,  
                                     8,  
                                     bitmapBytesPerRow,  
                                     colorSpace,  
                                     kCGImageAlphaPremultipliedLast);  
    //Core Foundation中通过含有Create、Alloc的方法名字创建的指针,需要使用CFRelease()函数释放  
    CGColorSpaceRelease( colorSpace );  
    return context;  
}  

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

获得以像素为单位的长和宽,开始处理位图中每个像素的值,生成指定效果
[html] view plaincopy
CGImageRef inImageRef = [inImage CGImage];  
                GLuint w = CGImageGetWidth(inImageRef);  
                GLuint h = CGImageGetHeight(inImageRef);  
                  
                int wOff = 0;  
                int pixOff = 0;  
                  
                //双层循环按照长宽的像素个数迭代每个像素点  
                for(GLuint y = 0;y< h;y++)  
                {  
                    pixOff = wOff;  
                      
                    for (GLuint x = 0; x<w; x++)  
                    {  
                        int red = (unsigned char)imgPixel[pixOff];  
                        int green = (unsigned char)imgPixel[pixOff+1];  
                        int blue = (unsigned char)imgPixel[pixOff+2];  
                        int alpha=(unsigned char)imgPixel[pixOff+3];  
                        //NSLog(@"1------r=%d,g=%d,b=%d,a=%d,",red,green,blue,alpha);  
                        changeRGBA(&red, &green, &blue, &alpha, f);  
                        //NSLog(@"2------r=%d,g=%d,b=%d,a=%d,",red,green,blue,alpha);  
                        //NSLog(@"--------------------------------------");  
                        //回写数据  
                        imgPixel[pixOff] = red;  
                        imgPixel[pixOff+1] = green;  
                        imgPixel[pixOff+2] = blue;  
                        imgPixel[pixOff+3] = alpha;  
                          
                        //将数组的索引指向下四个元素  
                        pixOff += 4;  
                    }  
                    wOff += w * 4;  
                }  
                  
                NSInteger dataLength = w*h* 4;  

创建生成image所需的参数
[html] view plaincopy
//下面的代码创建要输出的图像的相关参数  
                CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, imgPixel, dataLength, NULL);  
                if (!provider) {  
                    failedBlock(@"创建输出图像的相关参数失败!");  
                }else{  
                    // prep the ingredients  
                    int bitsPerComponent = 8;  
                    int bitsPerPixel = 32;  
                    int bytesPerRow = 4 * w;  
                    CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();  
                    CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;  
                    CGColorRenderingIntent renderingIntent = kCGRenderingIntentDefault;  
                      
                    //创建要输出的图像  
                    CGImageRef imageRef = CGImageCreate(w, h,  
                                                        bitsPerComponent,  
                                                        bitsPerPixel,  
                                                        bytesPerRow,  
                                                        colorSpaceRef,  
                                                        bitmapInfo,  
                                                        provider,  
                                                        NULL, NO, renderingIntent);  
                    if (!imageRef) {  
                        failedBlock(@"创建输出图像失败!");  
                    }else{  
                        UIImage *my_Image = [UIImage imageWithCGImage:imageRef];  
                          
                        CFRelease(imageRef);  
                        CGColorSpaceRelease(colorSpaceRef);  
                        CGDataProviderRelease(provider);  
                          
                        succeedBlock(my_Image);  
                    }  

下面附上几组原作者李海峰写的颜色矩阵的数值
[html] view plaincopy
//ColorMatrix From Android  
//lomo  
const float colormatrix_lomo[] = {  
    1.7f,  0.1f, 0.1f, 0, -73.1f,  
    0,  1.7f, 0.1f, 0, -73.1f,  
    0,  0.1f, 1.6f, 0, -73.1f,  
    0,  0, 0, 1.0f, 0 };  
  
//黑白  
const float colormatrix_heibai[] = {  
    0.8f,  1.6f, 0.2f, 0, -163.9f,  
    0.8f,  1.6f, 0.2f, 0, -163.9f,  
    0.8f,  1.6f, 0.2f, 0, -163.9f,  
    0,  0, 0, 1.0f, 0 };  
//旧化  
const float colormatrix_huajiu[] = {   
    0.2f,0.5f, 0.1f, 0, 40.8f,  
    0.2f, 0.5f, 0.1f, 0, 40.8f,   
    0.2f,0.5f, 0.1f, 0, 40.8f,   
    0, 0, 0, 1, 0 };  
  
//哥特  
const float colormatrix_gete[] = {   
    1.9f,-0.3f, -0.2f, 0,-87.0f,  
    -0.2f, 1.7f, -0.1f, 0, -87.0f,   
    -0.1f,-0.6f, 2.0f, 0, -87.0f,   
    0, 0, 0, 1.0f, 0 };  
  
//锐色  
const float colormatrix_ruise[] = {   
    4.8f,-1.0f, -0.1f, 0,-388.4f,  
    -0.5f,4.4f, -0.1f, 0,-388.4f,   
    -0.5f,-1.0f, 5.2f, 0,-388.4f,  
    0, 0, 0, 1.0f, 0 };  
  
  
//淡雅  
const float colormatrix_danya[] = {   
    0.6f,0.3f, 0.1f, 0,73.3f,  
    0.2f,0.7f, 0.1f, 0,73.3f,   
    0.2f,0.3f, 0.4f, 0,73.3f,  
    0, 0, 0, 1.0f, 0 };  
  
//酒红  
const float colormatrix_jiuhong[] = {   
    1.2f,0.0f, 0.0f, 0.0f,0.0f,  
    0.0f,0.9f, 0.0f, 0.0f,0.0f,   
    0.0f,0.0f, 0.8f, 0.0f,0.0f,  
    0, 0, 0, 1.0f, 0 };  
  
//清宁  
const float colormatrix_qingning[] = {   
    0.9f, 0, 0, 0, 0,   
    0, 1.1f,0, 0, 0,   
    0, 0, 0.9f, 0, 0,   
    0, 0, 0, 1.0f, 0 };  
  
//浪漫  
const float colormatrix_langman[] = {   
    0.9f, 0, 0, 0, 63.0f,   
    0, 0.9f,0, 0, 63.0f,   
    0, 0, 0.9f, 0, 63.0f,   
    0, 0, 0, 1.0f, 0 };  
  
//光晕  
const float colormatrix_guangyun[] = {   
    0.9f, 0, 0,  0, 64.9f,  
    0, 0.9f,0,  0, 64.9f,  
    0, 0, 0.9f,  0, 64.9f,  
    0, 0, 0, 1.0f, 0 };  
  
//蓝调  
const float colormatrix_landiao[] = {  
    2.1f, -1.4f, 0.6f, 0.0f, -31.0f,   
    -0.3f, 2.0f, -0.3f, 0.0f, -31.0f,  
    -1.1f, -0.2f, 2.6f, 0.0f, -31.0f,   
    0.0f, 0.0f, 0.0f, 1.0f, 0.0f  
};  
  
//梦幻  
const float colormatrix_menghuan[] = {  
    0.8f, 0.3f, 0.1f, 0.0f, 46.5f,   
    0.1f, 0.9f, 0.0f, 0.0f, 46.5f,   
    0.1f, 0.3f, 0.7f, 0.0f, 46.5f,   
    0.0f, 0.0f, 0.0f, 1.0f, 0.0f  
};  
  
//夜色  
const float colormatrix_yese[] = {  
    1.0f, 0.0f, 0.0f, 0.0f, -66.6f,  
    0.0f, 1.1f, 0.0f, 0.0f, -66.6f,   
    0.0f, 0.0f, 1.0f, 0.0f, -66.6f,   
    0.0f, 0.0f, 0.0f, 1.0f, 0.0f  
};  
</span>

  • 0
    点赞
  • 1
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值