- 浏览: 659554 次
- 性别:
- 来自: 北京
文章分类
最新评论
-
lizaochengwen:
网络请求碰到的中文乱码使用encodeURL吧- (NSStr ...
iPhone开发/iPad开发 中文乱码问题 -
hhb19900618:
还是没弄懂怎么解决了中文乱码? 正确代码能重写贴出吗
iPhone开发/iPad开发 中文乱码问题 -
zhengjj_2009:
我的理解是讲ipa文件解压缩之后再重新打包,已经破坏了签名,所 ...
xcodebuild和xcrun实现自动打包iOS应用程序 -
zhengjj_2009:
我参考你的“ 从ipa格式的母包生成其它渠道包的shell脚本 ...
xcodebuild和xcrun实现自动打包iOS应用程序 -
同一片天空:
问题果然解决了
iOS 搭建 XMPP实现环境
引用
跟着这个教程,你会通过实际动手的经验来学习Core Image技术,亲身体验如何应用一些不同的滤镜来实时地产生各种神奇的效果。
Core Image是一个很强大的框架。它可以让你简单地应用各种滤镜来处理图像,比如修改鲜艳程度, 色泽, 或者曝光。 它利用GPU(或者CPU,取决于客户)来非常快速、甚至实时地处理图像数据和视频的帧。多个Core Image滤镜可以叠加在一起,从而可以一次性地产生多重滤镜效果。这种多重滤镜的优点在于它可以生成一个改进的滤镜,从而一次性的处理图像达到目标效果,而不是对同一个图像顺序地多次应用单个滤镜。每一个滤镜都有属于它自己的参数。这些参数和滤镜信息,比如功能、输入参数等都可以通过程序来查询。用户也可以来查询系统从而得到当前可用的滤镜信息。到目前为止,Mac上只有一部分Core Image滤镜可以在iOS上使用。但是随着这些可使用滤镜的数目越来越多,API可以用来发现新的滤镜属性。
Core Image是一个很强大的框架。它可以让你简单地应用各种滤镜来处理图像,比如修改鲜艳程度, 色泽, 或者曝光。 它利用GPU(或者CPU,取决于客户)来非常快速、甚至实时地处理图像数据和视频的帧。多个Core Image滤镜可以叠加在一起,从而可以一次性地产生多重滤镜效果。这种多重滤镜的优点在于它可以生成一个改进的滤镜,从而一次性的处理图像达到目标效果,而不是对同一个图像顺序地多次应用单个滤镜。每一个滤镜都有属于它自己的参数。这些参数和滤镜信息,比如功能、输入参数等都可以通过程序来查询。用户也可以来查询系统从而得到当前可用的滤镜信息。到目前为止,Mac上只有一部分Core Image滤镜可以在iOS上使用。但是随着这些可使用滤镜的数目越来越多,API可以用来发现新的滤镜属性。
Core Image 总览
开始之前,让我们谈谈Core Image框架中最重要的几个类:
CIContext. 所有图像处理都是在一个CIContext 中完成的,这很像是一个Core Image处理器或是OpenGL的上下文。
CIImage. 这个类保存图像数据。它可以从UIImage、图像文件、或者是像素数据中构造出来。
CIFilter. 滤镜类包含一个字典结构,对各种滤镜定义了属于他们各自的属性。滤镜有很多种,比如鲜艳程度滤镜,色彩反转滤镜,剪裁滤镜等等。
在新建一个项目过程中,你会依次用到这些类。
让我们开始吧
打开Xcode, 用iOSApplicationSingle View Application 模板创建一个项目。输入CoreImageFun作为产品的名字。选择iPhone作为设备类型,并且确保只勾选Use Storyboards和Use Automatic Reference Counting两个选项。
首先,让我们导入Core Image框架。在Mac上,这个过程是QuartzCore框架的一部分;但是在iOS上,这个是单独的一个框架。在左侧文件导航栏中,进入项目文件夹。选择Build Phases标签页,扩展Link Binaries和Library group, 点击“+”来添加按钮;找到CoreImage框架并且双击完成添加。
第二步,下载教程资源,把其中的image.png添加到项目中,我们的创建设置就完成了。
之后,打开MainStoryboard.storyboard, 把图像视图拖拽到视图控制器中,并把它的模式设定为Aspect Fit使得它的位置和维度近似如下图所示:
同时,打开Assistant Editor,确保编辑器显示ViewController.h, 并从UIImageView拖拽到@interface以下。把Connection设置到指向Outlet, 并命名为imageView,之后点击Connect进行连接。
编译运行来确保到目前为止每一步都是正确的。如果一切正常,你将会看到一个空屏幕。这时,我们的初始化设置就完成了,下面我们就进入Core Image部分!
基本的图像滤镜
作为第一个尝试,我们先简单的让图像通过一个CIFilter 之后显示在屏幕上。每一次当我们想应用一个CIFilter的时候都要有以下四个步骤:
创建一个 CIImage 对象: CIImage 有如下的初始化方法: imageWithURL:, imageWithData:, imageWithCVPixelBuffer:, 和 imageWithBitmapData:bytesPerRow:size:format:colorSpace:。但是大多数时候你只会经常用到imageWithURL。
创建一个 CIContext: 一个 CIContext 可以是基于CPU或是GPU的。它可以被重用,所以你不用每次都创建一个。但是当输出CIImage对象的时候你至少一定会需要一个CIContext。
创建一个CIFilter: 当你创建滤镜的时候,你可以在上面配置一定数量的属性。具体的属性取决于你所要用的滤镜。
输出滤镜:这个滤镜会输出一个图像成为CIImage。 你可以用CIContext把它转化为一个UIImage ,具体过程如下。
让我们看看这是如何实现的。把下面的代码加入到viewDidLoad中的ViewController.m里面。
CIImage *beginImage = [CIImage imageWithContentsOfURL:fileNameAndPath]; CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone" keysAndValues: kCIInputImageKey, beginImage, @"inputIntensity", @0.8, nil]; CIImage *outputImage = [filter outputImage]; UIImage *newImage = [UIImage imageWithCIImage:outputImage]; self.imageView.image = newImage;
让我们依次看看这些代码都做了什么事情
前两行创建了一个NSURL 对象, 包含指向图形文件的路径。
下面,用imageWithContentsOfURL方法创建CIImage。
之后,创建CIFilter对象。一个 CIFilter 构造函数有两个输入,分别是滤镜的名字,还有规定了滤镜属性的键值和取值的字典。 每一个滤镜会有它自己唯一的键值和一组有效的取值。CISepiaTone 滤镜只能选两个值: KCIInputImageKey (一个CIImage) 和 @”inputIntensity”。 后者是一个封装成NSNumber (用新的文字型语法)的浮点小数,取值在0和1 之间。大部分的滤镜有默认值,只有CIImage是个例外。你必须提供一个值给它,因为它没有默认值。从滤镜中导出CIImage很简单,只需要用outputImage方法。
一旦你有了导出的 CIImage,你就可以把它转化为一个 UIImage。 在新的iOS6中,UIImage 方法+ imageWithCIImage方法可以实现从CIImage 到UIImage 到转化。一旦转化完成,我们就可以让UIImage 显示在之前添加的图像视图里。
编辑运行项目,你将会看到你的图片如下图一般,已经被墨色调滤镜处理过。恭喜你,你已经成功掌握并运用了CIImage和CIFilters。
把它放在上下文中
在进行下一步之前,有一个优化的方法很实用。我前面提到过,你需要一个CIContext来进行CIFilter,但是在上面的例子中我们没有提到这个对象。因为我们调用的UIImage方法(imageWithCIImage)已经自动地为我们完成了这个步骤。它生成了一个CIContext并且用它来处理图像的过滤。这使得调用Core Image的接口变得很简单。
但是,有一个主要的问题是,它的每次调用都会生成一个CIContext。CIContext本来是可以重用以便提高性能和效率的。比如下面我们要谈到的例子,如果你想用滑动条来选择过滤参数取值,每次改变滤镜参数都会自动生成一个CIContext, 使得性能非常差。
让我们想个好办法搞定这个问题。删除你之前添加到viewDidLoad里面的代码,用下面的代码取而代之:
CIImage *beginImage = [CIImage imageWithContentsOfURL:fileNameAndPath]; // 1 CIContext *context = [CIContext contextWithOptions:nil]; CIFilter *filter = [CIFilter filterWithName:@"CISepiaTone" keysAndValues: kCIInputImageKey, beginImage, @"inputIntensity", @0.8, nil]; CIImage *outputImage = [filter outputImage]; // 2 CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]]; // 3 UIImage *newImage = [UIImage imageWithCGImage:cgimg]; self.imageView.image = newImage; // 4 CGImageRelease(cgimg);
再让我逐步解释一下这部分代码
在这部分代码中,你创建了CIContext对象。CIContext 构造函数的输入是一个NSDictionary。 它规定了各种选项,包括颜色格式以及内容是否应该运行在CPU或是GPU上。对于这个应用程序,默认值是可以用的。所以你只需要传入nil作为参数就好了。
在这里你用上下文对象里的一个方法来画一个CGImage。 调用上下文中的createCGImage:fromRect:和提供的CIImage可以生成一个CGImageRef。
下面,你用UIImage + imageWithCGImage,从CGImage中创建一个UIImage。
最后,开放 CGImageRef接口。 CGImage 是一个C接口,即使有ARC,也需要你自己来做内存管理。
编译运行,确保正常工作。
在这个例子中,添加CIContext的创建 和你自己来创建的区别不大。但是在下一部分中,你将会看到当你实现动态改变滤镜参数的时候的重大性能差别。
改变滤镜的取值
上面可以看到,Core Image滤镜很好用,但是这些只是非常初级的应用。让我们添加一个滑动条使得我们能够实时动态地调整图像设置。
打开MainStoryboard.storyboard, 拖拽一个滑动条到图像窗口的下部 (如下图)。
确保Assistant Editor 是可见的并且显示ViewController.h。 控制@interface下的滑动条。把Connection设置到Action,把名字设置成amountSliderValueChanged, 把Event设置成Value Changed,接下来让我们把滑动条连接到输出。再一次控制@interface下的滑动条, 但是这一次把Connection设置到Outlet,把名字设置成amountSlider,
之后点击 Connect。
每一次滑动条改变位置,你需要重新用新的值进行图像过滤。但是你一定不想每次都重做整个过程,那将会非常的低效。你其实只需要在你的类中改变一小部分,从而使得你已经在viewDidLoad方法中创建的对象还能继续被使用。最重要的一步是在任何需要被用到的地方多次重用CIContext。如果你每次都重新创建它,你的程序将会非常地慢。另一步优化是你可以保存CIFilter和存有初始图像的CIImage。对每一个输出你都需要生成一个新的CIFilter,但是每次初始用到的图像始终是同一个。
你需要添加一些实例变量来完成这个任务。
把下面的3个实例变量添加到ViewController.m里你自己的@implementation中。
@implementation ViewController { CIContext *context; CIFilter *filter; CIImage *beginImage; }
并且, 改变viewDidLoad方法中的变量, 使得他们调用实例变量,而不是声明新的本地变量:
beginImage = [CIImage imageWithContentsOfURL:fileNameAndPath]; context = [CIContext contextWithOptions:nil]; filter = [CIFilter filterWithName:@"CISepiaTone" keysAndValues:kCIInputImageKey, beginImage, @"inputIntensity", @0.8, nil];
现在,你将实现changeValue方法来实现改变CIFilter 字典中@”inputIntensity”键值的功能。在我们实现了这个改变之后,你还需要重复如下一些步骤:
从CIFilter 中得到CIImage
把CIImage转化成 CGImageRef.
把CGImageRef 转化成UIImage, 在图像视图中显示出来。
所以用如下的部分替换amountSliderValueChanged方法:
- (IBAction)amountSliderValueChanged:(UISlider *)slider { float slideValue = slider.value; [filter setValue:@(slideValue) forKey:@"inputIntensity"]; CIImage *outputImage = [filter outputImage]; CGImageRef cgimg = [context createCGImage:outputImage fromRect:[outputImage extent]]; UIImage *newImage = [UIImage imageWithCGImage:cgimg]; self.imageView.image = newImage; CGImageRelease(cgimg); }
你将会注意到,在方法定义中,你已经把变量类型从(id)转化成了(UISlider *)。 你知道你只会用这个方法来从你的UISlider中获得数据,所以你可以做这个转变,不会影响其他的部分。如果我们保持变量类型为(id)不变, 则必须把它转化为UISlider,否则下一行将会报错。确保头文件中的声明也做了相应修改。
你可以从滑动条中获取浮点数。滑动条有相应的默认设置 – 最小值0,最大值0,默认值0.5。这刚好是这个CIFilter的合理取值,简直太方便了!
CIFilter 有相应的方法可以任由我们在字典中设置不同键值的取值。在这里你只需要把@”inputIntensity” 键设置成一个NSNumber 对象,它的取值是你从滑动条上得到的任意浮点数。
代码的其他部分应该看上去很像,因为都是遵循和viewDidLoad方法同样的逻辑。你将会反复重用这些代码。从现在开始,你将用changeSlider方法来为UIImageView提供CIFilter输出。
编译运行,你将会得到一个可以实时改变图片墨色调数值的滑动条!
从相册中读取照片
既然你现在可以改变滤镜的取值, 真正有趣的东西才刚刚开始。如果你不想要这幅花朵的图像怎么办呢?让我们建立一个UIImagePickerController, 使得你可以任意从相册中选取图片读取到你的项目中来进行任意修改。你需要创建一个按钮来打开相册视图。所以打开ViewController.xib,把一个按钮拖拽到滑动条的右下方,且命名为“相册”(Photo Album)
确保Assistant Editor 是可见的并且显示ViewController.h。 控制@interface下的按钮。把Connection设置到Action,把名字设置成loadPhoto, 把Event设置成Touch Up Inside,之后点击Connect。
接下来切换到ViewController.m,实现loadPhoto方法如下:
- (IBAction)loadPhoto:(id)sender { UIImagePickerController *pickerC = [[UIImagePickerController alloc] init]; pickerC.delegate = self; [self presentViewController:pickerC animated:YES completion:nil]; }
第一行代码实例化一个新的UIImagePickerController。之后,你设置图像选取代理为ViewController。在这里,你将会看到一个警告消息。你需要把ViewController设置为UIImagePickerControllerDelegate和UINaviationControllerDelegate,并且在代理协议下实现所有的方法。
还是在ViewController.m中,改变类型拓展如下:
@interface ViewController () <UIImagePickerControllerDelegate, UINavigationBarDelegate> @end
现在实现下面的两个方法:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { [self dismissViewControllerAnimated:YES completion:nil]; NSLog(@"%@", info); } - (void)imagePickerControllerDidCancel: (UIImagePickerController *)picker { [self dismissViewControllerAnimated:YES completion:nil]; }
在两个方法里,你摒除了UIPickerController,而用新的代理来完成相应的功能。如果你在代理中没有相应的实现,那你就只有一直瞪着图像选择器发呆了。第一个方法是不完整的, 它只是一个标志位,用来注销所选图像的信息。imagePickerControllerDidCancel方法用来清除PickerController。
编译运行,按那个“相册”(Photo Album)按钮, 图像选择器就会跳出来,显示你相册里所有的照片。如果你在模拟器上运行, 可能就不会看到任何照片。在模拟器或者没有照相机的设备上,你可以用Safari浏览器保存照片到你的相册。打开Safari浏览器, 找到一个图片, 按住过一会,就会弹出一个对话框让你保存图片。下次你运行你的应用程序,就会看到这个图片了。
下面是在当你选定一个图片之后,控制台中应该显示的信息(会根据所选图片内容相应有所不同):
2012-09-20 17:30:52.561 CoreImageFun[3766:c07] { UIImagePickerControllerMediaType = "public.image"; UIImagePickerControllerOriginalImage = ""; UIImagePickerControllerReferenceURL = "assets-library://asset/asset.JPG? id=253312C6-A454-45B4-A9DA-649126A76CA5&ext=JPG"; }
注意,在字典中有一个字段就是专门为被选择的原始图片而设置的。这个字段就正是你需要取出并且过滤的!
既然我们已经知道怎么选取一个图片,那么我们怎么设置CIImage beganImage来调用这个图片呢?
简单!只需要如下修改代理的方法:
- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info { [self dismissViewControllerAnimated:YES completion:nil]; UIImage *gotImage = [info objectForKey:UIImagePickerControllerOriginalImage]; beginImage = [CIImage imageWithCGImage:gotImage.CGImage]; [filter setValue:beginImage forKey:kCIInputImageKey]; [self amountSliderValueChanged:self.amountSlider]; }
你需要从你选择的图片中创建一个新的CIImage。在UIImagePickerControllerOriginalImage键值是个常数的情况下,你可以通过寻找字典中的取值得到图片的 UIImage 代理。注意最好用一个常数,而不是一个硬编码的字符串,因为Apple可以在未来改变键的名字。从UIImagePickerController代理协议参考中你可以找到所有的常数键。
你需要转化这些成为一个 CIImage,但是并没有一个方法可以把一个 UIImage转化成一个CIImage。然而你有[CIImage imageWithCGImage:] 方法。它可以通过调用UIImage.CGImage来从UIImage中得到CIImage。那么你完全可以做一样的事情!
于是你设置滤镜字典中的相应键,使得导入的图片正是你刚刚常见的CIImage。
最后一行可能看起来会很奇怪。还记得我是怎么阐述changeView的代码是用最新的值来运行滤镜,并且根据运行结果更新图像视图的吗?
你需要再做一遍这个工作,所以你只需要调用一遍changeValue方法。即使滑动条的值没有改变,你仍然可以使用哪个方法的代码来完成这个工作。
你可以拆开那部分代码形成单独的方法。而且随着你做的事情越来越复杂,你也希望用这种方式尽量避免混淆。但是就当前这个问题而言,你的目的只是想用changeValue方法,所以你传入amountSlider,得到正确的值就好了。
编译运行,你现在就可以编辑更新你相册里的任意图片或照片了。
在把你的图片做了墨色调处理之后,怎么保持它呢。你可以截屏,但是你没那么土!让我们学学如何保存处理后的图片到你的相册里。
保存到相册
为了保存到相册,你需要一个AssetsLibrary框架。进入到项目容器里,选择Build Phases标签页,扩展Link Binaries和Library group, 点击“+”来添加按钮。找到AssetsLibrary框架,选择进行添加。
之后把下面的#import 内容添加到ViewController.m的顶部。
#import <AssetsLibrary/AssetsLibrary.h>
你需要明白一件事情,那就是当你保存一张照片到相册的时候,即使你退出了这个应用,这个过程仍然可以继续。
这点可能会导致一些问题,因为GPU在当你切换应用的时候会停止当前的工作。如果照片还没有保存完毕就退出了程序,那可能以后就找不到这个要保存的照片了。
对于这个问题的解决方法是利用CPU的CIRendering上下文。然而默认设备是GPU,而且GPU比CPU快很多。所以你其实可以创建第二个CIContext,只为了保存这个图片。
让我们添加一个新按钮来实现对当前编辑照片的保存。打开MainStoryboard, 添加一个新按钮,标记为“保存”(Save to Album)。
之后把这个按钮连接到一个新的savePhoto方法, 就像你刚做完的过程一样。之后切换到ViewController.m 并且按照如下代码实现这个方法:
- (IBAction)savePhoto:(id)sender { // 1 CIImage *saveToSave = [filter outputImage]; // 2 CIContext *softwareContext = [CIContext contextWithOptions:@{kCIContextUseSoftwareRenderer : @(YES)} ]; // 3 CGImageRef cgImg = [softwareContext createCGImage:saveToSave fromRect:[saveToSave extent]]; // 4 ALAssetsLibrary* library = [[ALAssetsLibrary alloc] init]; [library writeImageToSavedPhotosAlbum:cgImg metadata:[saveToSave properties] completionBlock:^(NSURL *assetURL, NSError *error) { // 5 CGImageRelease(cgImg); }]; }
在这段代码中:
从滤镜中得到CIImage输出
创建一个新的、基于软件的CIContext
生成CGImageRef.
保存CGImageRef 到图片库
释放CGImage。最后一步在回调部分发生,使得只有在完成之后才会用到它。
编译并且在真正的设备上运行这个应用,你就可以永久保存你想要的图片到相册里。
图像元数据怎么处理呢?
让我们简单谈谈图像的元数据。移动电话上拍摄的图像文件有一系列的数据相关联,比如GPS坐标,图像格式,图像朝向等等。具体来说,图像的朝向是你需要保存的数据。加载原始图像到CIImage,转化为CGImage, 进而转化为UIImage的过程去除掉了原始图像的元数据。为了保存图像的朝向,你需要记录并且恢复这些相关图像信息到UIImage。你可以通过添加一个新的私有实例变量到ViewController.m当中来达到这个目的。
@implementation ViewController { CIContext *context; CIFilter *filter; CIImage *beginImage; UIImageOrientation orientation; // New! }
下一步,当从相册里加载原始图像的时候,可以通过imagePickerController: didFinishPickingMediaWithInfo方法设定相应的元数据值。把下面几行代码加入到 “beginImage = [CIImage imageWithCGImage:gotImage.CGImage]” 这一行代码的前面:
orientation = gotImage.imageOrientation;
最终,改变amountSliderChanged中的代码,创建imageView对象中设定的UIImage:
UIImage *newImage = [UIImage imageWithCGImage:cgimg scale:1.0 orientation:orientation];
现在,如果你用非默认的朝向照一张照片, 这个朝向信息将会被保存下来。
还有其他什么滤镜可以用吗?
CIFilter 接口在Mac OS上有130个滤镜,外加可以定制滤镜的能力。 在iOS6中,有93个或更多;但是目前还不能实现在iOS平台上对滤镜的定制。希望以后可以做到。
为了找到可用的滤镜信息,你可以利用 [CIFilter filterNamesInCategory:kCICategoryBuiltIn] 方法。 这个方法会返回一列可用滤镜的名字。而且,每一个滤镜都有一个属性方法来返回一个包含滤镜信息的字典结构。这些信息包括滤镜的名字,滤镜的分类,滤镜的输入以及输入的默认值和可接受的值范围。
让我们为你的类整理出一个方法。调用这个方法可以在日志文件中打印出所有可用滤镜信息。把下面这个方法加入到viewDidLoad的上面:
- (void)logAllFilters { NSArray *properties = [CIFilter filterNamesInCategory: kCICategoryBuiltIn]; NSLog(@"%@", properties); for (NSString *filterName in properties) { CIFilter *fltr = [CIFilter filterWithName:filterName]; NSLog(@"%@", [fltr attributes]); } }
这个方法从filterNamesInCategory方法中获取可用滤镜的名字,先打印名字,之后对于在列表上的每一个名字,创建一个相应的滤镜,并且记录该滤镜中的属性字典。之后在viewDidLoad的底部调用下面这个方法:
[self logAllFilters];
你将会在输出中看到下面的内容:
天啊,简直有太多的滤镜了!
更复杂的滤镜链
既然我们已经学习了iOS6平台上所有可用的滤镜, 我们可以进一步看看如何创建一个更复杂的滤镜链。为了达到这个目的,我们需要创建一个专门的方法来处理CIImage。它将导入CIImage,过滤处理,之后返回一个CIImage。添加如下的方法:
-(CIImage *)oldPhoto:(CIImage *)img withAmount:(float)intensity { // 1 CIFilter *sepia = [CIFilter filterWithName:@"CISepiaTone"]; [sepia setValue:img forKey:kCIInputImageKey]; [sepia setValue:@(intensity) forKey:@"inputIntensity"]; // 2 CIFilter *random = [CIFilter filterWithName:@"CIRandomGenerator"]; // 3 CIFilter *lighten = [CIFilter filterWithName:@"CIColorControls"]; [lighten setValue:random.outputImage forKey:kCIInputImageKey]; [lighten setValue:@(1 - intensity) forKey:@"inputBrightness"]; [lighten setValue:@0.0 forKey:@"inputSaturation"]; // 4 CIImage *croppedImage = [lighten.outputImage imageByCroppingToRect:[beginImage extent]
本文固定链接: http://iphone.xiaoxiaostudio.net/2013/10/18/初学ios6-中的core-image技术/
发表评论
-
SOCK_STREAM和SOCK_DGRAM
2015-07-23 20:08 1640sock_stream 是有保障的(即能保证数据正确传送到 ... -
SOCKET bind INADDR_LOOPBACK和INADDR_ANY的区别
2015-07-23 19:49 2057今天写程序时候,服务器端启动了,然后客户端总是连接不上,con ... -
htons()
2015-07-23 19:26 580在C/C++写网络程序的时候,往往会遇到字节的网络顺序和主机顺 ... -
使用symbolicatecrash分析crash文件
2015-03-10 11:32 1179原文 http://www.cnblogs.com/ning ... -
程序设计中的计算复用(Computational Reuse)
2015-02-10 10:18 662从斐波那契数列说起 ... -
didReceiveMemoryWarning
2015-02-09 16:11 541IPhone下每个app可用的内存是被限制的,如果一个app使 ... -
iOS开发中怎么响应内存警告
2015-02-09 16:08 654好的应用应该在系统内存警告情况下释放一些可以重新创建的资源。在 ... -
ASIHTTPRequest多次重复请求的问题
2014-12-17 14:34 641在一个车票订购的项目中,点击一次订购,却生成了2次订单,通过抓 ... -
从 CloudKit 看 BaaS 服务的趋势
2014-09-26 11:51 726从 6 月份 WWDC 苹果发布 ... -
ios编程--AVCapture编程理解
2014-09-26 11:03 9230、媒体采集的几个东西。这里所需要明白的是,在这个流程中,这里 ... -
NSURLProtocol
2014-09-25 10:42 8191、http://nshipster.com/nsurlpro ... -
关于iOS8的extension插件
2014-09-25 10:41 1279关于iOS8的extension插件,有兴趣的同学可以参考一下 ... -
【转】ios app在itunesConnect里面的几种状态
2014-08-05 10:34 1145Waiting for Upload (Yellow) Ap ... -
[转]iOS Dev (45) iOS图标与切片处理工具Prepo
2014-02-07 17:02 1033iOS Dev (45) iOS图标与切片处理工具Prepo ... -
phoneGap开发IOS,JS调用IOS方法/phoneGap插件开发
2014-01-13 17:49 1244前沿 废话不说phoneGap是什么不多介绍,官方网站: h ... -
如何在IOS平台下搭建PhoneGap开发环境(PhoneGap2.5)
2014-01-13 15:23 747由于在下最近在做基于HTML5的跨平台移植,搭建环境的时候着实 ... -
xcode 4 制作静态库详解
2013-12-20 18:27 533最近在做Apple的IOS开发,有开发静态库的需求,本身IOS ... -
【翻译】ios教程-创建静态库
2013-12-20 18:19 3108作者:shede333 主页:htt ... -
封装自己的控件库:iPhone静态库的应用
2013-12-20 17:03 581由于iPhone 控件的极度匮乏和自定义组件在重用上的限制,在 ... -
iphone:使用NSFileManager取得目录下所有文件(遍历所有文件)
2013-11-18 17:56 869From:http://note.sdo.com/u/xiao ...
相关推荐
总的来说,《初识iOS 6开发:探索iOS SDK》是一本全面而实用的教程,涵盖了iOS开发的核心概念和技术,旨在帮助读者从零开始,逐步成长为熟练的iOS开发者。无论是对移动开发感兴趣的个人,还是希望提升团队技术水平的...
CoreImage是苹果iOS和macOS开发中的一个强大的图像处理框架,它提供了丰富的滤镜和图像分析功能,使得开发者能够轻松地实现复杂的图像编辑、合成和特效。在"CoreImage-master.zip"这个压缩包中,我们可以预见到一...
图像过滤器iOS 6+ 上的高级图像/照片过滤...Github 上第一个共享易于使用但专业的 CoreImage 过滤技术的操作系统存储库之一可供 iOS 开发人员级别的初学者和更高级别的用户使用,为 iPad、iPhone、iPod Touch 创建自己
- **Core Image**:Core Image框架为图像处理提供了强大的工具,本书介绍了一些基本的图像处理技术。 ### 7. 高级话题 - **通知中心**:iOS9增强了本地通知和远程推送通知的功能,本书提供了设置和接收通知的示例...
6. **RadioButton for iOS**:在iOS中,复选框(RadioButton)并非原生控件,但通过自定义控件可以实现。这个实例可能展示了如何创建具有iOS风格的复选框,提升用户界面的可用性。 7. **XBImageFilters for iOS**:...
首先,我们要了解iOS中处理图像的基本框架Core Image。Core Image是Apple提供的一个强大的图像处理框架,它包含了多种预设的滤镜,可以实时应用到图像和视频上。在"简单的滤镜demo"中,我们很可能会看到如何导入并...
《精通iOS开发 第7版》是一本深入探讨iOS应用程序开发的专业书籍,其归档文件包含了丰富的源代码和资源文件,旨在帮助开发者深入了解并熟练掌握iOS平台的开发技术。这一版本聚焦于最新的iOS版本,提供了全面的更新和...
书中内容涵盖了多个方面,包括自动引用计数(ARC)、Storyboard、iCloud、OpenGL ES 2.0与GLKit、UIKit自定义、Twitter集成、Newsstand、Core Image、回合制游戏、UIPageViewController以及其他一些新的iOS 5 API。...
6. **多媒体处理**:实例可能涉及音频、视频的播放与编辑,如AVFoundation框架的使用,以及处理图像(如相机、相册访问、图片处理)的UIImage和Core Image知识。 7. **推送通知与本地通知**:学习如何集成Apple ...
源码可能还包含了如何将这个功能集成到实际项目中的示例,这对于初学者理解如何在实际应用中运用这些技术非常有帮助。 总之,图片倒影的实现涉及到iOS图形和动画的核心知识,是iOS开发者必须掌握的技能之一。通过...
在iOS应用开发中,创建一个私人相册功能是一项常见的任务,尤其对于初学者来说,这是一个很好的练习项目,能够深入理解iOS应用的基本架构和媒体管理。本资源包包含了开发这样一个私人相册APP所需的图像资源、接口...
1. **图像处理框架**:在iOS中,通常会用到Core Image框架来实现滤镜效果。Core Image提供了一系列预定义的滤镜,允许开发者轻松地对图像进行实时处理。 2. **Swift或Objective-C编程**:根据源码的年代,代码可能...
在iOS应用开发中,滤镜合成是常见的图像处理技术,广泛应用于照片编辑、美颜、特效等场景。这个"简单的滤镜合成demo"提供了一个基础的实现,让我们深入探讨一下这个话题。 首先,滤镜合成涉及到的核心技术是Core ...
根据提供的文件信息,我们可以归纳出一系列与iOS开发相关的知识点,这些知识点覆盖了从入门到进阶的多个层次,旨在帮助初学者逐步成长为具备全面技能的iOS架构师。下面将详细介绍这些知识点: ### iOS开发基础 ###...
Beginning iOS 5 Development Exploring the iOS SDK 是一本旨在引导初学者进入iOS开发领域的经典书籍。这本书的源代码提供了丰富的示例和练习,帮助读者深入理解iOS应用开发的基础和核心技术。以下是一些关键的知识...
【超级猜图】是一款基于iOS平台的趣味猜图游戏,该项目提供了一个良好的学习资源,适合初学者或进阶开发者深入理解iOS应用开发。这个小项目包含了许多关键的iOS编程概念和技术,下面将对这些知识点进行详细阐述。 1...
"ImageFilterDemo"是一个适合初学者的简单示例,旨在帮助开发者快速入门iOS平台上的图片过滤技术。这个项目将教你如何使用苹果的Core Image框架来实现各种图像滤镜效果。 Core Image是iOS SDK中一个强大的图像处理...
《iOS 5编程实战秘籍》是一本专为开发者准备的中文指南,旨在深入解析iOS 5开发中的各种技术和实践。这本书通过丰富的示例代码,将理论与实践紧密结合,帮助读者掌握苹果移动平台上的应用程序开发。 该书内容涵盖...
6. **绘图上下文**:在`drawRect(_:)`方法中,我们获取到当前视图的`graphicsContext`,这是Core Graphics框架中的一个概念,用于实际的绘制操作。使用`setStrokeColor(_:for:)`设置线条颜色,`setLineWidth(_:)`...
在iOS开发中,实现这种效果通常涉及到Core Graphics和Core Image框架,这两个框架提供了丰富的图像处理和图形绘制能力。 首先,让我们深入了解一下阴影效果。在iOS应用中,阴影可以增加UI元素的深度感,使其看起来...