博客
关于我
强烈建议你试试无所不能的chatGPT,快点击我
ios 滤镜
阅读量:6267 次
发布时间:2019-06-22

本文共 6400 字,大约阅读时间需要 21 分钟。

hot3.png

今天重新看了一个巨人李海峰写的滤镜demo感觉非常的清晰易懂。

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

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

// 返回一个使用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;}
// 返回一个指针,该指针指向一个数组,数组中的每四个元素都是图像上的一个像素点的RGBA的数值(0-255),用无符号的char是因为它正好的取值范围就是0-255static 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;}
获得以像素为单位的长和宽,开始处理位图中每个像素的值,生成指定效果

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
创建生成image所需的参数

//下面的代码创建要输出的图像的相关参数                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);                    }
下面附上几组原作者李海峰写的颜色矩阵的数值

//ColorMatrix From Android//lomoconst 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};

转载于:https://my.oschina.net/sunqichao/blog/102094

你可能感兴趣的文章
Yii用ajax实现无刷新检索更新CListView数据
查看>>
App 卸载记录
查看>>
南京大学周志华教授当选欧洲科学院外籍院士
查看>>
计算机网络与Internet应用
查看>>
Django 文件下载功能
查看>>
走红日本 阿里云如何能够赢得海外荣耀
查看>>
磁盘空间满引起的mysql启动失败:ERROR! MySQL server PID file could not be found!
查看>>
点播转码相关常见问题及排查方式
查看>>
[arm驱动]linux设备地址映射到用户空间
查看>>
弗洛伊德算法
查看>>
【算法之美】求解两个有序数组的中位数 — leetcode 4. Median of Two Sorted Arrays
查看>>
精度 Precision
查看>>
Android——4.2 - 3G移植之路之 APN (五)
查看>>
Linux_DHCP服务搭建
查看>>
[SilverLight]DataGrid实现批量输入(like Excel)(补充)
查看>>
秋式广告杀手:广告拦截原理与杀手组织
查看>>
翻译 | 摆脱浏览器限制的JavaScript
查看>>
闲扯下午引爆乌云社区“盗窃”乌云币事件
查看>>
02@在类的头文件中尽量少引入其他头文件
查看>>
JAVA IO BIO NIO AIO
查看>>