IOS Photo Editing Extensions|照片编辑扩展玩法

iOS 8之后,APPLE公司提供IOS应用扩展点Extension points(最近更新的ios10 又增加了iMessage功能扩展)。这些提供给操作系统的前所未有的访问,比如照片编辑的扩展,允许开发人员可以构建功能到系统相册应用。

比如实现以下照片编辑效果

photo extension.gif

或者自己做个贴图的编辑应用

photo extension2.gif

1、创建Photo Editing Extension Target

创建一个新的target,选择 Photo Editing Extension

IOS Photo Editing Extensions|照片编辑扩展玩法_第1张图片
new target.png

接着需要在info.plist添加配置信息

IOS Photo Editing Extensions|照片编辑扩展玩法_第2张图片
info.plist.png

NSExtensionPointIdentifier:照片编辑与扩展
PHSupportedMediaTypes:设置支持编辑的类型是image类型
NSExtensionMainStroyboard:storyboard名

创建之后你会发现新target下多了PhotoEditingViewControllerMainInterface.storyboard这两个文件,这两个是编辑图片时候的视图控制器,我们可以在storyboard上面创建UI

IOS Photo Editing Extensions|照片编辑扩展玩法_第3张图片
MainInterface.storyboard.png

这里我添加collectionView于底部,实现如下卡片式选择的效果

IOS Photo Editing Extensions|照片编辑扩展玩法_第4张图片
Screen Shot 2016-09-23 at 下午3.02.25.png

2、实现图片加载到控制器中

我们通过图库中【选择图片->进入编辑模式->选择编辑程序】 来进入我们的应用,控制器开启的时候,会进入到PHContentEditingController的以下代理方法里面

- (void)startContentEditingWithInput:(PHContentEditingInput *)contentEditingInput placeholderImage:(UIImage *)placeholderImage {
//在这里获取选择图片,显示到我们的控制器中    
    self.input = contentEditingInput;
    
    CGFloat imageWidth = placeholderImage.size.width;
    
    CGFloat imageHeight = placeholderImage.size.height;
    
    _proportion = imageWidth/imageHeight;
    
    self.imageView = [[UIImageView alloc]initWithFrame:CGRectMake(0, 0, self.view.bounds.size.width, self.view.bounds.size.width/_proportion)];
    
    self.imageView.contentMode = UIViewContentModeScaleAspectFit;
    
    self.imageView.userInteractionEnabled = YES;
    
    self.imageView.image = placeholderImage;
    
    [self.imageView addGestureRecognizer:self.tapGesture];
    
    self.imageView.center = CGPointMake(self.view.bounds.size.width/2, self.view.bounds.size.height/2);
    
    [self.view insertSubview:self.imageView belowSubview:self.toolView];
    
    _inputImage = placeholderImage;

}

3、处理图片

拿到将要编辑的图片之后,就要对图片进行修改了,我这里是给图片添加一个贴图,这里我就省略了collectionView的一些代理方法了,详情请移步Demo

#pragma mark - 绘制贴图到图片中
-(UIImage *)addImageLogo:(UIImage *)img text:(UIImage *)logo
{
    CGFloat selectImageW = 60.0f;
    
    CGFloat orginImageW = self.imageView.frame.size.width;

    CGFloat persen = selectImageW/orginImageW;
    
    //get image width and height
    int w = img.size.width;

    int h = img.size.height;

    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();

    //create a graphic context with CGBitmapContextCreate
    CGContextRef context = CGBitmapContextCreate(NULL, w, h, 8, 44 * w, colorSpace, kCGImageAlphaPremultipliedFirst);

    CGContextDrawImage(context, CGRectMake(0, 0, w, h), img.CGImage);

    CGContextDrawImage(context, CGRectMake(_iconPoint.x , _iconPoint.y-w*persen, w*persen, w*persen), [logo CGImage]);

    CGImageRef imageMasked = CGBitmapContextCreateImage(context);
    CGContextRelease(context);

    CGColorSpaceRelease(colorSpace);

    return [UIImage imageWithCGImage:imageMasked];

}

4、完成编辑、回调图片

当结束编辑的时候会来到这个代理方法里面(通过我们对图片的一系列处理之后,生成JPEG的 output 图片,回调给completionHandler

- (void)finishContentEditingWithCompletionHandler:(void (^)(PHContentEditingOutput *))completionHandler {
    // Update UI to reflect that editing has finished and output is being rendered.
    
    // Render and provide output on a background queue.
    dispatch_async(dispatch_get_global_queue(QOS_CLASS_DEFAULT, 0), ^{
        // Create editing output from the editing input.
        
        PHContentEditingOutput *output = [[PHContentEditingOutput alloc] initWithContentEditingInput:self.input];
        
        NSData *imageData = UIImageJPEGRepresentation([self addImageLogo:self.imageView.image text:_selectImage],1.0);
        
        PHAdjustmentData *adjustmentData = [[PHAdjustmentData alloc]initWithFormatIdentifier:formatIdentifier formatVersion:formatVersion data:imageData];
        
        // Provide new adjustments and render output to given location.
        output.adjustmentData = adjustmentData;
        
        NSData *renderedJPEGData = imageData;
        
        [renderedJPEGData writeToURL:output.renderedContentURL atomically:YES];
        
        // Call completion handler to commit edit to Photos.
        
        NSLog(@">>>>>>finishContent");
        
        completionHandler(output);
        
        // Clean up temporary files, etc.
    });
}

5、运行

选择Photo editing extension的target,然后command+R,选择运行到图库上

IOS Photo Editing Extensions|照片编辑扩展玩法_第5张图片
Debugging.png

接着。。。。

IOS Photo Editing Extensions|照片编辑扩展玩法_第6张图片
Paste_Image.png

(ps)如果找不到扩展应用,在more里面选中即可

IOS Photo Editing Extensions|照片编辑扩展玩法_第7张图片
more.png
choose.png

6、内存限制

扩展并不是完整的iOS应用程序,因此允许有限制地访问系统资源。更具体地说,如果它使用了太多的内存,操作系统将杀死一个扩展。所以,如果没有硬性限制,我建议尽量减少内存占用。
有以下建议可以做你的图片编辑的扩展的内存使用量保持在最低水平:

1、使用显示图像的尺寸:当开始编辑处理中,系统提供适当地缩放的屏幕图像。使用代替了原来的交互式编辑阶段,这将节省显示图片的内存。

** 2、限制Core Graphics上下文的数量:**如果需要使用上下文,则该数目应该减少到最低限度。

3、使用GPU:可通过Core Image或第三方框架GPUImage,减少内存占用。


小结:这个开发过程其实不复杂,而注意的一点就是内存的处理,尽量不要使用太占内存的操作。大家可以尝试一下其他的应用扩展,例如IOS10的IMessage 开发也是前所未有的尝试。

各位朋友可以尝试自己敲一下哈,还有各路大神多多指教!
附上Demo:Demo_1 、 Demo_2

你可能感兴趣的:(IOS Photo Editing Extensions|照片编辑扩展玩法)