• 图片编辑扩展

注:此教程来源于http://www.raywenderlich.com的《iOS8 by Tutorials》


1.准备

与(二)类似的使用Imgur作为图片来源
 

2.正文

添加Photo Editing Extension
之后在新生成的文件夹下找到MainInterface.storyboard为PhotoEditingViewController加上Size Classes,在这里我删掉原来的vc,加入新的vc,并设置它为启动界面,具体设置见我提供的源码中的storyboard文件,这里只具体写写它的实现类PhotoEditingViewController的使用方法。
还要注意的一点是:由于在新工程中要使用RWTImageFilterService.h,所以要在下面添加它的实现.m文件,否则会报错!!!
下面是PhotoEditingViewController.m代码,附有我的一些注释说明
 
 //
// PhotoEditingViewController.m
// JMImgure Photo
//
// Created by JackMa on 15/12/3.
// Copyright © 2015年 JackMa. All rights reserved.
// #import "PhotoEditingViewController.h"
#import <Photos/Photos.h>
#import <PhotosUI/PhotosUI.h>
#import "RWTImageFilterService.h" @interface PhotoEditingViewController () <PHContentEditingController> @property (strong) PHContentEditingInput *input; @property (nonatomic, weak) IBOutlet UIImageView *imageView;
@property (nonatomic, weak) IBOutlet UIButton *undoButton;
@property (nonatomic, weak) IBOutlet UIButton *addButton; @property (strong, nonatomic) RWTImageFilterService *imageFilterService;
@property (strong, nonatomic) NSString *currentFilterName;
@property (strong, nonatomic) UIImage *filteredImage; @end @implementation PhotoEditingViewController //撤销的button
- (IBAction)undo:(id)sender {
self.imageView.image = self.input.displaySizeImage;
self.currentFilterName = nil;
self.filteredImage = nil;
} //添加过滤器
- (IBAction)addFilter:(id)sender {
UIAlertController *alert = [UIAlertController alertControllerWithTitle:@"过滤器" message:@"请选择一种过滤器" preferredStyle:UIAlertControllerStyleActionSheet];
//遍历字典
[self.imageFilterService.availableFilters enumerateKeysAndObjectsUsingBlock:^(id _Nonnull key, id _Nonnull obj, BOOL * _Nonnull stop) {
UIAlertAction *action = [UIAlertAction actionWithTitle:key style:UIAlertActionStyleDefault handler:^(UIAlertAction *action) {
//为图片添加过滤
self.filteredImage = [self.imageFilterService applyFilter:obj toImage:self.input.displaySizeImage];
self.imageView.image = self.filteredImage;
self.currentFilterName = obj;
}];
[alert addAction:action];
}];
UIAlertAction *cancel = [UIAlertAction actionWithTitle:@"取消" style:UIAlertActionStyleCancel handler:^(UIAlertAction * _Nonnull action) {
[alert dismissViewControllerAnimated:YES completion:nil];
}];
[alert addAction:cancel];
[self presentViewController:alert animated:YES completion:nil];
} - (void)viewDidLoad {
[super viewDidLoad]; self.imageView.contentMode = UIViewContentModeScaleAspectFit;
self.imageFilterService = [[RWTImageFilterService alloc] init];
} - (void)didReceiveMemoryWarning {
[super didReceiveMemoryWarning];
// Dispose of any resources that can be recreated.
} #pragma mark - PHContentEditingController //在原始编辑界面可以对图片进行调整,当你在这个App想获取的是最原始的图片,那么返回NO
//你想获取调整后的adjustmentData的话,那么返回YES
//只有图片经过调整才会调用此函数,否则默认NO
- (BOOL)canHandleAdjustmentData:(PHAdjustmentData *)adjustmentData {
return NO;
} //view Load后,view appear前调用,用来接受原始数据contentEditingInput
- (void)startContentEditingWithInput:(PHContentEditingInput *)contentEditingInput placeholderImage:(UIImage *)placeholderImage {
//canHandleAdjustmentData:返回YES的话,这里的contentEditingInput也会带上adjustmentData
//canHandleAdjustmentData:返回NO的话,这里只有原始图像displaySizeImage
self.input = contentEditingInput;
self.imageView.image = self.input.displaySizeImage;//将原始图片呈现出来
} //点击右上方完成button时调用
- (void)finishContentEditingWithCompletionHandler:(void (^)(PHContentEditingOutput *))completionHandler {
//异步处理图片
dispatch_async(dispatch_get_global_queue(DISPATCH_QUEUE_PRIORITY_DEFAULT, ), ^{
//创建output并设置
PHContentEditingOutput *output = [[PHContentEditingOutput alloc] initWithContentEditingInput:self.input];
NSData *archiveData = [NSKeyedArchiver archivedDataWithRootObject:self.currentFilterName];
#warning Please set your Photos Extension Name and Version here
PHAdjustmentData *adjustmentData = [[PHAdjustmentData alloc] initWithFormatIdentifier:@"qq100858433.JMImgure.JMImgure-Photo" formatVersion:@"1.0" data:archiveData];
output.adjustmentData = adjustmentData; UIImage *fullImage = [UIImage imageWithContentsOfFile:self.input.fullSizeImageURL.path];
fullImage = [self.imageFilterService applyFilter:self.currentFilterName toImage:fullImage]; //将转化后的图片存到renderedContentURL中
NSData *jpegData = UIImageJPEGRepresentation(fullImage, 1.0);
BOOL saved = [jpegData writeToURL:output.renderedContentURL options:NSDataWritingAtomic error:nil];
if (saved) {
//回调处理结果给Photos
//注:这里模拟机调试会出现无法显示修改后图片问题,真机调试没有问题
completionHandler(output);
} else {
NSLog(@"An error occurred during save");
completionHandler(nil);
}
// Clean up temporary files, etc.
});
} //点击左上方取消后调用
- (BOOL)shouldShowCancelConfirmation {
//返回YES,则会弹出AlertSheet让用户确认是否取消
//返回NO,则页面直接消失
return NO;
} //shouldShowCancelConfirmation或finishContentEditingWithCompletionHandler:
//之后调用,此函数在后台运行,负责清理临时文件
- (void)cancelContentEditing {
// Clean up temporary files, etc.
// May be called after finishContentEditingWithCompletionHandler: while you prepare output.
} @end

最后的说明:

在新建Photo Extension Target时,系统默认是只为图片添加扩展效果,那么视频呢

你可以在PHSupportedMediaTypes中修改你想支持的媒体类型

 
源码点击 包括未添加扩展的original版本和修改后版本

iOS8中添加的extensions总结(三)——图片编辑扩展的更多相关文章

  1. iOS8中添加的extensions总结(一)——今日扩展

    通知栏中的今日扩展 分享扩展 Action扩展 图片编辑扩展 文件管理扩展 第三方键盘扩展 注:此教程来源于http://www.raywenderlich.com的<iOS8 by Tutor ...

  2. iOS8中添加的extensions总结(四)——Action扩展

    Action扩展 注:此教程来源于http://www.raywenderlich.com的<iOS8 by Tutorials> 1.准备 本次教程利用网站bitly.com进行 bit ...

  3. iOS8中添加的extensions总结(二)——分享扩展

    分享扩展 注:此教程来源于http://www.raywenderlich.com的<iOS8 by Tutorials> 1.准备 这次例子来源于国外的图片分享网站Imgur.com 首 ...

  4. cocos2d-x 中添加显示文字的三种方式 LabelTTF 、LabelBMFont 和 LabelAtlas

    在 cocos2d-x 中有三个类可以在层或精灵中添加文字: LabelTTF LabelBMFont LabelAtlas LabelTTF 直接支持使用 TTF 字库,可以支持全部的中文,但是效率 ...

  5. ZH奶酪:PHP中添加HTML代码的三种方法

    php中添加HTML代码,就是php类型的文件中添加html代码~ 第一种是在HTML中加PHP. 大段大段的html代码中,在各个需要执行php的地方<?php .... ?> 比如 l ...

  6. cocos中添加显示文字的三种方式(CCLabelTTF 、CCLabelBMFont 和CCLabelAtlas)

    CCLabelTTF CCLabelTTF 每次调用 setString (即改变文字)的时候,一个新的OPENGL 纹理将会被创建..这意味着setString 和创建一个新的标签一样慢. 这个类使 ...

  7. 在VS中添加lib库的三种方法

    注意: 1.每种方法也要复制相应的DLL文件到相应目录,或者设定DLL目录的位置,具体方法为:"Properties" -> "Configuration Prop ...

  8. C# 往Datatable中添加新行的步骤

    以一个实例说明 //录入年份绑定 public void YearList(FineUIPro.DropDownList ddlYear) { //年份从15年到当前年//起止年份 ; int yea ...

  9. Spring中添加新的配置表,并对新的配置表进行处理

    实习过程中boss交代的任务(以下出现的代码以及数据只给出小部分,提供一个思路) 目的:Spring中添加新的配置表,并对新的配置表进行处理:替换的新的配置表要友好,同时保证替换前后功能不能发生变化. ...

随机推荐

  1. 嵌入式 python之str操作

    1.字符串的对齐方式:①:center(int[,str])>>> string = 'Fishhat'>>> string.center(55)'         ...

  2. Swift互用性:与 Cocoa 数据类型共舞(Swift 2.0版)-b

    本节内容包括: 字符串(Strings) 数值(Numbers) 集合类(Collection Classes) 错误(Errors) Foundation数据类型(Foundation Data T ...

  3. 转: memcpy的用法总结

    1.memcpy 函数用于 把资源内存(src所指向的内存区域) 拷贝到目标内存(dest所指向的内存区域):拷贝多少个?有一个size变量控制拷贝的字节数:函数原型:void *memcpy(voi ...

  4. poj 2886Who Gets the Most Candies?

    http://poj.org/problem?id=2886 #include <cstdio> #include <cstring> #include <algorit ...

  5. 其实,SSL也不是配通了就什么都不管的~~

    其中太多的中间人攻击需要去加强加固~~ 测试过A级是必须的!! https://www.ssllabs.com/ssltest/ 这网址两年前,我写过的哈

  6. CentOS卸载openoffice

    rpm -e `rpm -qa |grep openoffice` `rpm -qa |grep ooobasis` 这样算是比较彻底的

  7. [转载]监控 Linux 性能的 18 个命令行工具

    转自:http://www.kuqin.com/shuoit/20140219/338066.html 对于系统和网络管理员来说每天监控和调试Linux系统的性能问题是一项繁重的工作.在IT领域作为一 ...

  8. 同时安装Xcode6和Xcode7导致出现N多UUID 模拟器解决办法

    [摘要:1.完整退出Xcode 和 摹拟器 2.末端中输进以下两居指令 $ sudo killall -9 com.apple.CoreSimulator.CoreSimulatorService$ ...

  9. Sql 行转列、列转行及分页

    说明:本实例是以 SQL Server 2005 为运行环境的. 准备工作:创建一个名为 DB 的数据库(CREATE DATABASE DB). 一.T-SQL 行转列 1.创建如下表 CREATE ...

  10. Gmail邮件功能那么强大,GMail被封,在国内怎么用gmail收邮件?

    IT圈子里最热门的话题一定是:gmail被封,该怎么办?gmail由于强大的邮件功能,ITer一定是人手一个or多个,之前想要收发gmail使用imap或SMTP方式是可以在国内正常使用的,目前ima ...