iOS GPUImage研究一:图片滤镜


本片介绍关于图片滤镜的研究:xoxo_x 著


这里写图片描述


本文参考:https://github.com/BradLarson/GPUImage#gpuimage

下载地址:
https://github.com/BradLarson/GPUImage/tree/master/examples/iOS/SimpleImageFilter


步骤内容
第一步创建预览View 即必须的GPUImageView
第二步创建对象 即我们要用到的GPUImagePicture
第三步创建滤镜 即这里我们使用的 GPUImageSobelEdgeDetectionFilter
第四步设置纹理尺寸 添加滤镜 addTarget 并开始处理

效果如下:
这里写图片描述


第一步:

CGRect mainScreenFrame = [[UIScreen mainScreen] applicationFrame];  
GPUImageView *primaryView = [[GPUImageView alloc] initWithFrame:mainScreenFrame];
self.view = primaryView;

第二步:

 UIImage *inputImage = [UIImage imageNamed:@"WID-small.jpg"];
GPUImagePicture *sourcePicture = [[GPUImagePicture alloc] initWithImage:inputImage smoothlyScaleOutput:YES];

第三步:

GPUImageOutput *sepiaFilter = [[GPUImageSobelEdgeDetectionFilter alloc] init];

第四步:

//设置纹理尺寸[sepiaFilter forceProcessingAtSize:imageView.sizeInPixels];[sourcePicture addTarget:sepiaFilter];
[sepiaFilter addTarget:imageView];
//开始处理
[sourcePicture processImage];

如果想将图片保存下来需要使用:

- (void)useNextFrameForImageCapture;
- (UIImage *)imageFromCurrentFramebuffer;

或者使用:

- (UIImage *)imageByFilteringImage:(UIImage *)imageToFilter;

即:

[sepiaFilter useNextFrameForImageCapture];UIImage *nearestNeighborImage = [sepiaFilter imageFromCurrentFramebuffer];

或:

UIImage *inputImage = [UIImage imageNamed:@"Lambeau.jpg"];UIImage *nearestNeighborImage = [sepiaFilter imageByFilteringImage:inputImage];

//文件写入本地

    NSData *dataForPNGFile1 = UIImagePNGRepresentation(nearestNeighborImage);NSArray *paths = NSSearchPathForDirectoriesInDomains(NSDocumentDirectory, NSUserDomainMask, YES);NSString *documentsDirectory = [paths objectAtIndex:0];NSError *error = nil;if (![dataForPNGFile1 writeToFile:[documentsDirectory stringByAppendingPathComponent:@"Lambeau-Resized-fsk.png"] options:NSAtomicWrite error:&error]){return;}

图片处理分析:

一、分析GPUImageView

@interface GPUImageView : UIView 
{GPUImageRotationMode inputRotation;
}

继承:UIView 并遵守GPUImageInput协议

GPUImageInput协议内容如下:

@protocol GPUImageInput 
- (void)newFrameReadyAtTime:(CMTime)frameTime atIndex:(NSInteger)textureIndex;
- (void)setInputFramebuffer:(GPUImageFramebuffer *)newInputFramebuffer atIndex:(NSInteger)textureIndex;
- (NSInteger)nextAvailableTextureIndex;
- (void)setInputSize:(CGSize)newSize atIndex:(NSInteger)textureIndex;
- (void)setInputRotation:(GPUImageRotationMode)newInputRotation atIndex:(NSInteger)textureIndex;
- (CGSize)maximumOutputSize;
- (void)endProcessing;
- (BOOL)shouldIgnoreUpdatesToThisTarget;
- (BOOL)enabled;
- (BOOL)wantsMonochromeInput;
- (void)

二、分析GPUImagePicture

@interface GPUImagePicture : GPUImageOutput
{CGSize pixelSizeOfImage;BOOL hasProcessedImage;dispatch_semaphore_t imageUpdateSemaphore;
}// 初始化方法有很多
- (id)initWithURL:(NSURL *)url;
- (id)initWithImage:(UIImage *)newImageSource;
- (id)initWithCGImage:(CGImageRef)newImageSource;
- (id)initWithImage:(UIImage *)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput;
- (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput;
- (id)initWithImage:(UIImage *)newImageSource removePremultiplication:(BOOL)removePremultiplication;
- (id)initWithCGImage:(CGImageRef)newImageSource removePremultiplication:(BOOL)removePremultiplication;
- (id)initWithImage:(UIImage *)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput removePremultiplication:(BOOL)removePremultiplication;
- (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput removePremultiplication:(BOOL)removePremultiplication;// 处理和对输出图片大小进行更改
- (void)processImage;
- (CGSize)outputImageSize;/**
异步处理,回调*/
- (BOOL)processImageWithCompletionHandler:(void (^)(void))completion;
- (void)processImageUpToFilter:(GPUImageOutput *)finalFilterInChain withCompletionHandler:(void (^)(UIImage *processedImage))block;

三 、分析GPUImageSobelEdgeDetectionFilter (黑白漫画)

//起名为黑白漫画 、更好理解些

//所有的滤镜都是继承GPUImageFilter

GPUImageSobelEdgeDetectionFilter最终是继承GPUImageFilter的

@interface GPUImageFilter : GPUImageOutput <GPUImageInput>

所以,我们前面写到

GPUImageOutput *sepiaFilter = [[GPUImageSobelEdgeDetectionFilter alloc] init];

就是因为继承的关系。

四、分析addTaget

- (void)addTarget:(id)newTarget;
{NSInteger nextAvailableTextureIndex = [newTarget nextAvailableTextureIndex];[self addTarget:newTarget atTextureLocation:nextAvailableTextureIndex];if ([newTarget shouldIgnoreUpdatesToThisTarget]){_targetToIgnoreForUpdates = newTarget;}
}

我们可以看到addTarget 是GPUImageOutput的方法,也就是说,所有的GPUImageOutput的子类够可以使用这个函数,即继承与GPUImageOutput的类,如上面提到的GPUImageFilter。

- (void)addTarget:(id<GPUImageInput>)newTarget;

此外,凡是遵守这个协议的都是newTarget对象,如我们上面提到的GPUImageFilter以及GPUImageView。

本文所涉及到的代码:

#import 
#import "GPUImage.h"@interface SimpleImageViewController : UIViewController
{GPUImagePicture *sourcePicture;GPUImageOutput *sepiaFilter;}
#import "SimpleImageViewController.h"@implementation SimpleImageViewController- (void)viewDidLoad{    CGRect mainScreenFrame = [[UIScreen mainScreen] applicationFrame];  GPUImageView *primaryView = [[GPUImageView alloc] initWithFrame:mainScreenFrame];self.view = primaryView;[self setupDisplayFiltering];}#pragma mark Image filtering- (void)setupDisplayFiltering;
{UIImage *inputImage = [UIImage imageNamed:@"WID-small.jpg"];sourcePicture = [[GPUImagePicture alloc] initWithImage:inputImage smoothlyScaleOutput:YES];sepiaFilter = [[GPUImageSobelEdgeDetectionFilter alloc] init];GPUImageView *imageView = (GPUImageView *)self.view;[sepiaFilter forceProcessingAtSize:imageView.sizeInPixels]; [sourcePicture addTarget:sepiaFilter];[sepiaFilter addTarget:imageView];[sourcePicture processImage];
}

本文用到的图片:
这里写图片描述


本文来自互联网用户投稿,文章观点仅代表作者本人,不代表本站立场,不承担相关法律责任。如若转载,请注明出处。 如若内容造成侵权/违法违规/事实不符,请点击【内容举报】进行投诉反馈!

相关文章

立即
投稿

微信公众账号

微信扫一扫加关注

返回
顶部