程序员取悦女票的正确姿势---Tip1(iOS美容篇)
前言
女孩子都喜欢用美图工具进行图片美容,近来无事时,特意为某人写了个自定义图片滤镜生成器,安装到手机即可完成自定义滤镜渲染照片。app独一无二,虽简亦繁。
JH定律:
魔镜:最漂亮的女人是你老婆
魔镜:程序员不是木头人
核心技术
图片滤镜核心技术的基本思路如下:
核心技术流程
具体流程
1、创建一个图像处理工具类
注:该类实例包括一个图像处理方法,该方法在传入原始图像和一个颜色矩阵后生成一个处理好的图像。
@interface JHFeilterManager : NSObject
@property (nonatomic,copy)imageBlock imageBLOCK;
- (UIImage *)createImageWithImage:(UIImage *)inImage colorMatrix:(const float *)f;
2、获取图像的每个像素点的RGBA值数组
注:该c方法返回一个指针,该指针指向一个数组,数组中的每四个元素都是图像上的一个像素点的RGBA的数值(0-255),用无符号的char是因为它正好的取值范围就是0-255
static unsigned char *RequestImagePixelData(UIImage * inImage){
CGImageRef img = [inImage CGImage];
CGSize size = [inImage size];
//使用上面的函数创建上下文
CGContextRef cgctx = CreateRGBABitmapContex(img);
CGRect rect = {{0,0},{size.width,size.height}};
//将目标图像绘制到指定的上下文,实际为上下文内的bitmapData。
CGContextDrawImage(cgctx, rect, img);
unsigned char *data = CGBitmapContextGetData(cgctx);
//释放上面的函数创建的上下文
CGContextRelease(cgctx);
cgctx = NULL;
return data;
}
3、调整一个像素点的RGBA值
注:如下方法传入参数为数值指针和一个颜色矩阵,通过颜色矩阵调整指针指向地址存储的数值
static void changeRGB(int *red,int* green,int*blue,int*alpha ,const float *f){
int redV = *red;
int greenV = *green;
int blueV = *blue;
int alphaV = *alpha;
//色值重新计算 计算规则如下
*red = f[0] * redV + f[1]*greenV + f[2]*blueV + f[3] * alphaV + f[4];
*green = f[5] * redV + f[6]*greenV + f[7]*blueV + f[8] * alphaV+ f[9];
*blue = f[10] * redV + f[11]*greenV + f[12]*blueV + f[11] * alphaV+ f[14];
*alpha = f[15] * redV + f[16]*greenV + f[17]*blueV + f[18] * alphaV+ f[19];
*red < 0 ? (*red = 0):(0);
*red > 255 ? (*red = 255):(0);
*green < 0 ? (*green = 0):(0);
*green > 255 ? (*green = 255):(0);
*blue < 0 ? (*blue = 0):(0);
*blue > 255 ? (*blue = 255):(0);
*alpha < 0 ? (*alpha = 0):(0);
*alpha > 255 ? (*alpha = 255):(0);
}
4、遍历每个像素,调整色值
注意!!!
在以下方法中,不要立刻释放malloc方法生成的bitmapData内存空间指针,(可能有的朋友觉得已经把内存空间地址给了位图上下文就可以立马释放掉了,但是实际上,由于位图上下文在后来的图像渲染时,仍然需要这一块内存,因此不能在此处立马释放掉内存,之前拜读的几篇博客索性就不释放内存了,因此会导致内存泄漏,处理一些高清图像时,手机内存会轻易飙升到1G以上,而导致程序挂掉)不然会导致位图上下文的内容数据不能正常存在而导致图片生成失败,在这里需要一个全局内存指针来指向它,并且在合适的时候释放内存。
该方法中需要传入一个原始图片信息和一个颜色矩阵,颜色矩阵决定了图像的渲染效果,因此不同的滤镜效果可以通过设置不同的颜色矩阵进行转换,如果您不了解颜色矩阵,点击这里进行了解
- (UIImage *)createImageWithImage:(UIImage *)inImage colorMatrix:(const float *)f{
/* 图片位图像素值数组 */
unsigned char *imgPixel = RequestImagePixelData(inImage);
CGImageRef inImageRef = [inImage CGImage];
/* 获取像素的横向和纵向个数 */
long w = CGImageGetWidth(inImageRef);
long h = CGImageGetHeight(inImageRef);
int wOff = 0;
int pixOff = 0;
/* 遍历修改位图像素值 */
for (long y = 0; y<h; y++) {
pixOff = wOff;
for (long 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];
changeRGB(&red, &green, &blue, &alpha,f);
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;
//创建要输出的图像的相关参数
CGDataProviderRef provider = CGDataProviderCreateWithData(NULL, imgPixel, dataLength, NULL);
if (!provider) {
NSLog(@"创建输出图像相关参数失败!");
}else{
//每个像素点每个颜色的空间大小 单位为bit
int bitsPerComponent = 8;
//每个像素的空间大小 单位为bit
int bitsPerPixel = 32;
//每一行的颜色点的个数 每个像素有4个颜色点 每行有2个点
ItemCount bytesPerRow = 4 * w;
//创建RBGA色彩空间
CGColorSpaceRef colorSpaceRef = CGColorSpaceCreateDeviceRGB();
//位图的组成部分信息
CGBitmapInfo bitmapInfo = kCGBitmapByteOrderDefault;
//图像渲染参数 使用默认值
CGColorRenderingIntent rederingIntent = kCGRenderingIntentDefault;
//创建要输出的图像,参数依次为 宽、高、每个像素点的大小、每行占用空间大小、颜色空间、位图信息、相关输出参数
CGImageRef imageRef = CGImageCreate(w, h,bitsPerComponent, bitsPerPixel, bytesPerRow, colorSpaceRef, bitmapInfo, provider,NULL, NO, rederingIntent);
if (!imageRef) {
NSLog(@"创建输出图像失败");
}else{
UIImage *my_image = [UIImage imageWithCGImage:imageRef];
CFRelease(imageRef);
CGColorSpaceRelease(colorSpaceRef);
CGDataProviderRelease(provider);
if (_imageBLOCK) {
_imageBLOCK(my_image);
}
NSData *data = UIImageJPEGRepresentation(my_image, 1.0);
//在此释放位图空间
free(bitmap);
return [UIImage imageWithData:data];
}
}
return nil;
}
5、UI搭建
UI界面非常简单,就是一张大图、20个颜色矩阵的信息录入框和两个按钮组成,代码就不过多赘述了,有需要的话可以到这里下载demo,喜欢的话不防给个star哦。
成果展示
成型的demo就是这个样子喽!
相关文章:

MySQL的安装配置(win7 64-bit)
MySQL的安装配置(win7 64-bit) 转,整理。 MySQL 版本是 mysql-noinstall-5.1.66-winx64.zip(免安装版) mysql-workbench-gpl-5.2.44-win32.msi mysql-connector-java-5.1.22 mysql 配置数据库编码为utf-8(my.ini中指定)…

Sourse Insight使用教程及常见的问题解决办法
1、下载安装 2、创建项目new project(注意不是file-->new ),而是project-->new project,输入项目名称和密码. 3、添加文件,其实就是将你的整个项目文件添加到project中。 4、close就可以打开了。 具体参考道客巴巴一篇文章:Source_Insight教程及技…

android surface 平板,Surface平板能升级安卓4.0吗
Surface平板电脑暂时不能升级安卓4.0。Surface平板电脑x86架构的版本搭载了英特尔Core i5 Ivy Bridge双核处理器,而ARM架构的版本搭载了Nvidia代工的ARM单核处理器。Surface平板电脑采用镁合金机身,具有x86和ARM架构两个版本,x86架构的版本屏…
iOS - 实现映客首页 TabBar 和滑动隐藏 NavBar 和 TabBar
原文链接:http://www.jianshu.com/p/72228667cd7a之前在做直播的时候,参照了映客 App,发现其首页的效果还挺不错,在网上找了一下相关仿映客 App 代码和博客,大部分都是说如何播放直播流和推流,对于 UI 这块…

WinCE项目应用之车载导航
WinCE车载导航系统是我过去几年投入精力比较多的一个项目。我的主要工作内容是BSP的移植、硬件模块的调试和WinCE系统的深度定制。如TDA7415驱动、TDA7415均衡器、慧翰车载蓝牙模块、华为EM730的3G通信模块、四线电阻式触摸屏驱动的优化、3G拨号助手、LCD调试助手、WIFI模块AR6…

记录下,我们平时开发当中不得不知道的HTTP状态码
上面是我对博客园页面加载的时候,获取的AJAX读取资源的截图。 上述列表告诉我们了,返回的HTTP状态码,分为200(正常),304(不修改)和同时返回的资源大小和完成时间等。 这个工具可以很…

rmd文件怎么转换html文件,提取.Rmd文件的html依赖项(包含htmlwidgets)
题我怎样才能创建一个将.Rmd文件(包含htmlwidgets代码)作为输入的函数,并输出一个包含其JavaScript / CSS依赖项的html文件?具体来说,当渲染为html时,临时文件rmarkdown为pandoc的–include-in-header参数生成.细节示例 – myfile.Rmd:This is some text…

教你实现GPUImage【OpenGL渲染原理】
原文出处: 袁峥Seemygo(袁峥Seemygo) 一、前言 本篇主要讲解GPUImage底层是如何渲染的,GPUImage底层使用的是OPENGL,操控GPU来实现屏幕展示 由于网上OpenGL实战资料特别少,官方文档对一些方法也是解释不清楚,避免广大…

构建之法阅读笔记02
在这次的阅读过程中我了解到了如何给别人提意见,给我最大的启发是乔布斯对其下属提意见的小故事,当其下属把iphone的图标都设计成了矩形的时候,乔布斯建议他把图标设计成带圆角的正方形,而其下属一开始却并没有接受乔的意见&#…
Windows Server 2008 R2 配置笔记,密码设置为任意长度,远程桌面终端连接数的设置...
图片显示不完全时,可在新标签页打开。 Windows Server 2008 R2 配置{ 安装企业版(Enterprise Editon),因为企业版功能全面,并且比数据中心版更容易配置{ 各版本功能概述在版本概览页面。详细参数对比在版本概览页面右边有链接&…

html5图片灰度显示,HTML5 组件Canvas实现图像灰度化
HTML5发布已经有很长一段时间了,一直以来从来没有仔细的看过,过年刚来随便看看发现HTML5中的Canvas组件功能是如此的强大,不怪很多牛人预言Flash已死,死不死不是我要关心的,我关心的Canvas可以很轻松在网页中实现简单相…

SqlParameter参数方式操作数据库(存储过程)
访问数据库: View Code using System; using System.Data; using System.Configuration; using System.Linq; using System.Web; using System.Web.Security; using System.Web.UI; using System.Web.UI.HtmlControls; using System.Web.UI.WebControls; using Syst…

视频编解码之理论概述 和即时通信
前言 即时通讯应用中的实时音视频技术,几乎是IM开发中的最后一道高墙。原因在于:实时音视频技术 音视频处理技术 网络传输技术 的横向技术应用集合体,而公共互联网不是为了实时通信设计的。有关实时音视频开发时的技术难题请参见《音视频云…

图论:关于二分图的总结(转载)
二分图是这样一个图,它的顶点可以分类两个集合X和Y,所有的边关联在两个顶点中,恰好一个属于集合X,另一个属于集合Y。 最大匹配:图中包含边数最多的匹配称为图的最大匹配。 完美匹配:…

动态加载的html没有js效果,JS利用html5实现loadding动态加载效果代码实例
51前端window.οnlοadfunction(){var Loading function (canvas, options) {this.canvas document.getElementById(canvas);this.options options;};Loading.prototype{constructor: Loading,show: function(){var canvas this.canvas,begin this.options.begin,old thi…
iOS 自动布局框架 – Masonry 详解
来源:伯乐在线 - 刘小壮 如有好文章投稿,请点击 → 这里了解详情 如需转载,发送「转载」二字查看说明 目前iOS开发中大多数页面都已经开始使用Interface Builder的方式进行UI开发了,但是在一些变化比较复杂的页面,还是…

GDC2016 Epic Games【Bullet Train】 新风格的VR-FPS的制作方法
追求“舒适”和“快感”的VR游戏设计方法http://game.watch.impress.co.jp/docs/news/20160318_749016.html【Bullet Train】演讲的状况在游戏的创造历史上,有那种决定性的创新,以及高完成度的作品,对于FPS风格来说,【DOOM】就是这…

例4-1和例4-2和例4-3
public class ComputerCircleArea{ public static void main(String args[]){ double radius; double area; radius163.16; area3.14*radius*radius; System.out.printf("半径是%5.3f的圆的面积:\n%5.3f\n",radius,area); }} class Circle{ double radius; doubl…

html中的两种标记,如何在html选项标记中实现两种不同的对齐?
下面是一个单空间js解决方案,与scott everden的jquery示例一起使用。我只在firefox中测试过,但这应该足够开始了。javascriptvar MIN_SPACES_BETWEEN_VALS 3;function mkOption(left, right, total){var str left;var spaces total - left.length - right.length;for(x 0;x…

html标签(2)--有序列表与无序列表
有一些内容形式,用div来实现非常麻烦,也不适合 例如一些表格形式 无序列表 ul 代表列表 li 代表列表中的项 list-style 控制列表的样式 有序列表 ol 代表列表 li 代表列表中的项 <!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN…

Swift3实现的绘制股票K线库, FastImageCache提升图片的加载和渲染速度,Chameleon颜色框架
代码1:用Swift3实现的绘制股票K线库 for iOS & macOS代码地址:网页链接代码2:FastImageCache是Path团队开发的一个开源库,用于提升图片的加载和渲染速度,让基于图片的列表滑动起来更顺畅。代码地址:网页链接代码3:…

传智播客还收费 兄弟会都是免费的
【传智播客还收费 兄弟会都是免费的 兄弟连兄弟会it开发培训 www.itxdh.net 企鹅群:499956522 高端人才培养就到【兄弟连兄弟会it开发培训】纯免费的高端IT人才培养】 传智播客,一个多么具有戏剧性的词眼,以前张孝祥老师建校的初衷就是为了让…

用计算机的英语造句process,process的用法总结大全
process的意思n. 过程,工序,做事方法,工艺流程vt. 加工,处理,审阅,审核vi. 列队行进adj. 经过特殊加工(或处理)的变形:过去式: processed; 现在分词:processing; 过去分词:processed;process用法process可以…
iOS进阶之页面性能优化
作者: hi_xgb 地址: http://www.jianshu.com/p/1b5cbf155b31 前言 在软件开发领域里经常能听到这样一句话,“过早的优化是万恶之源”,不要过早优化或者过度优化。我认为在编码过程中时刻注意性能影响是有必要的,但凡事都有个度,不…

LabelMe图像数据集下载
Download MATLAB Toolbox for the LabelMe Image Database 利用Matlab Toolbox工具箱下载图像库 一、下载Matlab Toolbox工具箱 1. Github repository We maintain the latest version of the toolbox on github. To pull the latest version, make sure that "git" …

win8计算机管理没有用户组,Win8右键计算机管理提示“该文件没有与之关联的程序”怎么办?...
最近有Win8用户反映,右键计算机管理的时候,出现提示“该文件没有与之关联的程序来执行该操作”,这让用户非常苦恼。那么,Win8右键计算机管理提示“该文件没有与之关联的程序”怎么办呢?下面,我们就一起往下…
Objective-C 自动生成文档工具:appledoc
来源:iOS_小松哥 www.jianshu.com/p/fd4d8d6b6177 如有好文章投稿,请点击 → 这里了解详情 由于最近琐事比较多,所以好久没有写文章了。今天我们聊一聊Objective-C自动生成文档。 做项目的人多了,就需要文档了。手工写文档是一件…

linux命令--提升
查看系统进程:top 查看磁盘空间: df -h 查询系统负载: uptime , 以下显示输入uptime的信息: 04:03:58 up 10 days, 13:19, 1 user, load average: 0.54, 0.40, 0.20 1.当前时间 04:03:58 2.系统已运行的时间 10 days, 13:19 3.前在线用户…

git 从远程主服务器当中创建新分支
现有版本; h20, h28,h26,i8 h28,h26,i8是从H20下面创建的。 需求: 从H28下面创建新分支继续开发。 思路: 所有代码均是放置到H20上仓库当中,首先下载H20完整仓库,也就是.git文件夹当中内容,其本质是一个ZIP…

涉密计算机用户账号设置审批表,北京邮电大学涉密计算机配置审批表.PDF
北京邮电大学涉密计算机配置审批表北京邮电大学涉密计算机配置审批表使用部门 品牌型号涉密计算机类型 ?台式机 ?便携机 资产编号用途 ?科研 ?办公 ?其他 配置日期硬盘序列号中央处理器硬盘容量CPU基本配置 内 存显示器品牌型号MAC 地址操作系统版本 操作系统安装时间放置…