GPUImageAPI文档之GPUImageOutput类

王朝学院·作者佚名  2016-08-27
窄屏简体版  字體: 小  |  中  |  大  |  超大  

GPUImageOutput类将静态图像纹理上传到OpenGL ES中,然后使用这些纹理去处理进程链中的下一个对象。它的子类可以获得滤镜处理后的图片功能。[本文讲的很少,由于有许多地方不清楚,以后会更新]

方法

- (void)setInputFramebufferForTarget:(id<GPUImageInput>)target atIndex:(NSInteger)inputTextureIndex

说明:用于设置指定纹理的输入帧缓冲区的尺寸

参数:target是具体的对象,它接受了GPUImageInput的协议,例如:当我们使用[GPUImageLookupFilter]滤镜时,target就是一个GPUImageLookupFilter的实例。

- (void)addTarget:(id<GPUImageInput>)newTarget atTextureLocation:(NSInteger)textureLocation

说明:添加target

- (void)removeTarget:(id<GPUImageInput>)targetToRemove

说明:删除指定的target

- (void)removeAllTargets

说明:删除所有target

- (UIImage *)imageFromCurrentFramebufferWithOrientation:(UIImageOrientation)imageOrientation

说明:从帧缓冲区中取回对象,打印在屏幕中。

参数:imageOrientation时当前设备的手持方向

- (CGImageRef)newCGImageByFilteringCGImage:(CGImageRef)imageToFilter

说明:使用一张静态图片做滤镜纹理

完整代码

#import"GPUImageContext.h"#import"GPUImageFramebuffer.h"#ifTARGET_ipHONE_SIMULATOR || TARGET_OS_IPHONE#import<UIKit/UIKit.h>#else//For now, just redefine this on the Mactypedef NS_ENUM(NSInteger, UIImageOrientation) {

UIImageOrientationUp,//default orientationUIImageOrientationDown,//180 deg rotationUIImageOrientationLeft,//90 deg CCWUIImageOrientationRight,//90 deg CWUIImageOrientationUpMirrored,//as above but image mirrored along other axis. horizontal flipUIImageOrientationDownMirrored,//horizontal flipUIImageOrientationLeftMirrored,//vertical flipUIImageOrientationRightMirrored,//vertical flip};#endifvoidrunOnMainQueueWithoutDeadlocking(void(^block)(void));voidrunSynchronouslyOnVideoPRocessingQueue(void(^block)(void));voidrunAsynchronouslyOnVideoProcessingQueue(void(^block)(void));voidrunSynchronouslyOnContextQueue(GPUImageContext *context,void(^block)(void));voidrunAsynchronouslyOnContextQueue(GPUImageContext *context,void(^block)(void));voidreportAvailableMemoryForGPUImage(NSString *tag);

@class GPUImageMovieWriter;/** GPUImage's base source object

Images or frames of video are uploaded from source objects, which are subclasses of GPUImageOutput. These include:

- GPUImageVideoCamera (for live video from an iOS camera)

- GPUImageStillCamera (for taking photos with the camera)

- GPUImagePicture (for still images)

- GPUImageMovie (for movies)

Source objects upload still image frames to OpenGL ES as textures, then hand those textures off to the next objects in the processing chain.*/@interface GPUImageOutput : NSObject

{

GPUImageFramebuffer*outputFramebuffer;

NSMutableArray*targets, *targetTextureIndices;

CGSize inputTextureSize, cachedMaximumOutputSize, forcedMaximumSize;

BOOL overrideInputSize;

BOOL allTargetsWantMonoChromeData;

BOOL usingNextFrameForImageCapture;

}

@property(readwrite, nonatomic) BOOL shouldSmoothlyScaleOutput;

@property(readwrite, nonatomic) BOOL shouldIgnoreUpdatesToThisTarget;

@property(readwrite, nonatomic, retain) GPUImageMovieWriter*audioEncodingTarget;

@property(readwrite, nonatomic, unsafe_unretained) id<GPUImageInput>targetToIgnoreForUpdates;

@property(nonatomic, copy)void(^frameProcessingCompletionBlock)(GPUImageOutput*, CMTime);

@property(nonatomic) BOOL enabled;

@property(readwrite, nonatomic) GPUTextureOptions outputTextureOptions;///@name Managing targets- (void)setInputFramebufferForTarget:(id<GPUImageInput>)target atIndex:(NSInteger)inputTextureIndex;- (GPUImageFramebuffer *)framebufferForOutput;- (void)removeOutputFramebuffer;- (void)notifyTargetsAboutNewOutputTexture;/** Returns an array of the current targets.*/- (NSArray*)targets;/** Adds a target to receive notifications when new frames are available.

The target will be asked for its next available texture.

See [GPUImageInput newFrameReadyAtTime:]

@param newTarget Target to be added*/- (void)addTarget:(id<GPUImageInput>)newTarget;/** Adds a target to receive notifications when new frames are available.

See [GPUImageInput newFrameReadyAtTime:]

@param newTarget Target to be added*/- (void)addTarget:(id<GPUImageInput>)newTarget atTextureLocation:(NSInteger)textureLocation;/** Removes a target. The target will no longer receive notifications when new frames are available.

@param targetToRemove Target to be removed*/- (void)removeTarget:(id<GPUImageInput>)targetToRemove;/** Removes all targets.*/- (void)removeAllTargets;///@name Manage the output texture- (void)forceProcessingAtSize:(CGSize)frameSize;- (void)forceProcessingAtSizeRespectingaspectRatio:(CGSize)frameSize;///@name Still image processing- (void)useNextFrameForImageCapture;-(CGImageRef)newCGImageFromCurrentlyProcessedOutput;-(CGImageRef)newCGImageByFilteringCGImage:(CGImageRef)imageToFilter;//Platform-specific image output methods//If you're trying to use these methods, remember that you need to set -useNextFrameForImageCapture before running -processImage or running video and calling any of these methods, or you will get a nil image#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE

- (UIImage *)imageFromCurrentFramebuffer;- (UIImage *)imageFromCurrentFramebufferWithOrientation:(UIImageOrientation)imageOrientation;- (UIImage *)imageByFilteringImage:(UIImage *)imageToFilter;- (CGImageRef)newCGImageByFilteringImage:(UIImage *)imageToFilter;#else- (NSImage *)imageFromCurrentFramebuffer;- (NSImage *)imageFromCurrentFramebufferWithOrientation:(UIImageOrientation)imageOrientation;- (NSImage *)imageByFilteringImage:(NSImage *)imageToFilter;- (CGImageRef)newCGImageByFilteringImage:(NSImage *)imageToFilter;#endif-(BOOL)providesMonochromeOutput;

@end

#import"GPUImageOutput.h"#import"GPUImageMovieWriter.h"#import"GPUImagePicture.h"#import<mach/mach.h>voidrunOnMainQueueWithoutDeadlocking(void(^block)(void))

{if([NSThread isMainThread])

{

block();

}else{

dispatch_sync(dispatch_get_main_queue(), block);

}

}voidrunSynchronouslyOnVideoProcessingQueue(void(^block)(void))

{

dispatch_queue_t videoProcessingQueue=[GPUImageContext sharedContextQueue];#if!OS_OBJECT_USE_OBJC#pragmaclang diagnostic push#pragmaclang diagnostic ignored "-Wdeprecated-declarations"if(dispatch_get_current_queue() ==videoProcessingQueue)#pragmaclang diagnostic pop#elseif(dispatch_get_specific([GPUImageContext contextKey]))#endif{

block();

}else{

dispatch_sync(videoProcessingQueue, block);

}

}voidrunAsynchronouslyOnVideoProcessingQueue(void(^block)(void))

{

dispatch_queue_t videoProcessingQueue=[GPUImageContext sharedContextQueue];#if!OS_OBJECT_USE_OBJC#pragmaclang diagnostic push#pragmaclang diagnostic ignored "-Wdeprecated-declarations"if(dispatch_get_current_queue() ==videoProcessingQueue)#pragmaclang diagnostic pop#elseif(dispatch_get_specific([GPUImageContext contextKey]))#endif{

block();

}else{

dispatch_async(videoProcessingQueue, block);

}

}voidrunSynchronouslyOnContextQueue(GPUImageContext *context,void(^block)(void))

{

dispatch_queue_t videoProcessingQueue=[context contextQueue];#if!OS_OBJECT_USE_OBJC#pragmaclang diagnostic push#pragmaclang diagnostic ignored "-Wdeprecated-declarations"if(dispatch_get_current_queue() ==videoProcessingQueue)#pragmaclang diagnostic pop#elseif(dispatch_get_specific([GPUImageContext contextKey]))#endif{

block();

}else{

dispatch_sync(videoProcessingQueue, block);

}

}voidrunAsynchronouslyOnContextQueue(GPUImageContext *context,void(^block)(void))

{

dispatch_queue_t videoProcessingQueue=[context contextQueue];#if!OS_OBJECT_USE_OBJC#pragmaclang diagnostic push#pragmaclang diagnostic ignored "-Wdeprecated-declarations"if(dispatch_get_current_queue() ==videoProcessingQueue)#pragmaclang diagnostic pop#elseif(dispatch_get_specific([GPUImageContext contextKey]))#endif{

block();

}else{

dispatch_async(videoProcessingQueue, block);

}

}voidreportAvailableMemoryForGPUImage(NSString *tag)

{if(!tag)

tag=@"Default";structtask_basic_info info;

mach_msg_type_number_t size=sizeof(info);

kern_return_t kerr=task_info(mach_task_self(),

TASK_BASIC_INFO,

(task_info_t)&info,&size);if( kerr ==KERN_SUCCESS ) {

NSLog(@"%@ - Memory used: %u", tag, (unsignedint)info.resident_size);//in bytes}else{

NSLog(@"%@ - Error: %s", tag, mach_error_string(kerr));

}

}

@implementation GPUImageOutput

@synthesize shouldSmoothlyScaleOutput=_shouldSmoothlyScaleOutput;

@synthesize shouldIgnoreUpdatesToThisTarget=_shouldIgnoreUpdatesToThisTarget;

@synthesize audioEncodingTarget=_audioEncodingTarget;

@synthesize targetToIgnoreForUpdates=_targetToIgnoreForUpdates;

@synthesize frameProcessingCompletionBlock=_frameProcessingCompletionBlock;

@synthesize enabled=_enabled;

@synthesize outputTextureOptions=_outputTextureOptions;#pragmamark -#pragmamark Initialization and teardown

-(id)init;

{if(!(self =[super init]))

{returnnil;

}

targets=[[NSMutableArray alloc] init];

targetTextureIndices=[[NSMutableArray alloc] init];

_enabled=YES;

allTargetsWantMonochromeData=YES;

usingNextFrameForImageCapture=NO;//set default texture options_outputTextureOptions.minFilter =GL_LINEAR;

_outputTextureOptions.magFilter=GL_LINEAR;

_outputTextureOptions.wrapS=GL_CLAMP_TO_EDGE;

_outputTextureOptions.wrapT=GL_CLAMP_TO_EDGE;

_outputTextureOptions.internalFormat=GL_RGBA;

_outputTextureOptions.format=GL_BGRA;

_outputTextureOptions.type=GL_UNSIGNED_BYTE;returnself;

}- (void)dealloc

{

[self removeAllTargets];

}#pragmamark -#pragmamark Managing targets

- (void)setInputFramebufferForTarget:(id<GPUImageInput>)target atIndex:(NSInteger)inputTextureIndex;

{

[target setInputFramebuffer:[self framebufferForOutput] atIndex:inputTextureIndex];

}- (GPUImageFramebuffer *)framebufferForOutput;

{returnoutputFramebuffer;

}- (void)removeOutputFramebuffer;

{

outputFramebuffer=nil;

}- (void)notifyTargetsAboutNewOutputTexture;

{for(id<GPUImageInput> currentTargetintargets)

{

NSInteger indexOfObject=[targets indexOfObject:currentTarget];

NSInteger textureIndex=[[targetTextureIndices objectAtIndex:indexOfObject] integerValue];

[self setInputFramebufferForTarget:currentTarget atIndex:textureIndex];

}

}- (NSArray*)targets;

{return[NSArray arrayWithArray:targets];

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

{

NSInteger nextAvailableTextureIndex=[newTarget nextAvailableTextureIndex];

[self addTarget:newTarget atTextureLocation:nextAvailableTextureIndex];if([newTarget shouldIgnoreUpdatesToThisTarget])

{

_targetToIgnoreForUpdates=newTarget;

}

}- (void)addTarget:(id<GPUImageInput>)newTarget atTextureLocation:(NSInteger)textureLocation;

{if([targets containsObject:newTarget])

{return;

}

cachedMaximumOutputSize=CGSizeZero;

runSynchronouslyOnVideoProcessingQueue(^{

[self setInputFramebufferForTarget:newTarget atIndex:textureLocation];

[targets addObject:newTarget];

[targetTextureIndices addObject:[NSNumber numberWithInteger:textureLocation]];

allTargetsWantMonochromeData= allTargetsWantMonochromeData &&[newTarget wantsMonochromeInput];

});

}- (void)removeTarget:(id<GPUImageInput>)targetToRemove;

{if(![targets containsObject:targetToRemove])

{return;

}if(_targetToIgnoreForUpdates ==targetToRemove)

{

_targetToIgnoreForUpdates=nil;

}

cachedMaximumOutputSize=CGSizeZero;

NSInteger indexOfObject=[targets indexOfObject:targetToRemove];

NSInteger textureIndexOfTarget=[[targetTextureIndices objectAtIndex:indexOfObject] integerValue];

runSynchronouslyOnVideoProcessingQueue(^{

[targetToRemove setInputSize:CGSizeZero atIndex:textureIndexOfTarget];

[targetToRemove setInputRotation:kGPUImageNoRotation atIndex:textureIndexOfTarget];

[targetTextureIndices removeObjectAtIndex:indexOfObject];

[targets removeObject:targetToRemove];

[targetToRemove endProcessing];

});

}- (void)removeAllTargets;

{

cachedMaximumOutputSize=CGSizeZero;

runSynchronouslyOnVideoProcessingQueue(^{for(id<GPUImageInput> targetToRemoveintargets)

{

NSInteger indexOfObject=[targets indexOfObject:targetToRemove];

NSInteger textureIndexOfTarget=[[targetTextureIndices objectAtIndex:indexOfObject] integerValue];

[targetToRemove setInputSize:CGSizeZero atIndex:textureIndexOfTarget];

[targetToRemove setInputRotation:kGPUImageNoRotation atIndex:textureIndexOfTarget];

}

[targets removeAllObjects];

[targetTextureIndices removeAllObjects];

allTargetsWantMonochromeData=YES;

});

}#pragmamark -#pragmamark Manage the output texture

- (void)forceProcessingAtSize:(CGSize)frameSize;

{

}- (void)forceProcessingAtSizeRespectingAspectRatio:(CGSize)frameSize;

{

}#pragmamark -#pragmamark Still image processing

- (void)useNextFrameForImageCapture;

{

}-(CGImageRef)newCGImageFromCurrentlyProcessedOutput;

{returnnil;

}-(CGImageRef)newCGImageByFilteringCGImage:(CGImageRef)imageToFilter;

{

GPUImagePicture*stillImageSource =[[GPUImagePicture alloc] initWithCGImage:imageToFilter];

[self useNextFrameForImageCapture];

[stillImageSource addTarget:(id<GPUImageInput>)self];

[stillImageSource processImage];

CGImageRef processedImage=[self newCGImageFromCurrentlyProcessedOutput];

[stillImageSource removeTarget:(id<GPUImageInput>)self];returnprocessedImage;

}-(BOOL)providesMonochromeOutput;

{returnNO;

}#pragmamark -#pragmamark Platform-specific image output methods#ifTARGET_IPHONE_SIMULATOR || TARGET_OS_IPHONE

- (UIImage *)imageFromCurrentFramebuffer;

{

UIDeviceOrientation deviceOrientation=[[UIDevice currentDevice] orientation];

UIImageOrientation imageOrientation=UIImageOrientationLeft;switch(deviceOrientation)

{caseUIDeviceOrientationPortrait:

imageOrientation=UIImageOrientationUp;

break;caseUIDeviceOrientationPortraitUpsideDown:

imageOrientation=UIImageOrientationDown;

break;caseUIDeviceOrientationLandscapeLeft:

imageOrientation=UIImageOrientationLeft;

break;caseUIDeviceOrientationLandscapeRight:

imageOrientation=UIImageOrientationRight;

break;default:

imageOrientation=UIImageOrientationUp;

break;

}return[self imageFromCurrentFramebufferWithOrientation:imageOrientation];

}- (UIImage *)imageFromCurrentFramebufferWithOrientation:(UIImageOrientation)imageOrientation;

{

CGImageRef cgImageFromBytes=[self newCGImageFromCurrentlyProcessedOutput];

UIImage*finalImage = [UIImage imageWithCGImage:cgImageFromBytes scale:1.0orientation:imageOrientation];

CGImageRelease(cgImageFromBytes);returnfinalImage;

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

{

CGImageRef image=[self newCGImageByFilteringCGImage:[imageToFilter CGImage]];

UIImage*processedImage =[UIImage imageWithCGImage:image scale:[imageToFilter scale] orientation:[imageToFilter imageOrientation]];

CGImageRelease(image);returnprocessedImage;

}- (CGImageRef)newCGImageByFilteringImage:(UIImage *)imageToFilter

{return[self newCGImageByFilteringCGImage:[imageToFilter CGImage]];

}#else- (NSImage *)imageFromCurrentFramebuffer;

{return[self imageFromCurrentFramebufferWithOrientation:UIImageOrientationLeft];

}- (NSImage *)imageFromCurrentFramebufferWithOrientation:(UIImageOrientation)imageOrientation;

{

CGImageRef cgImageFromBytes=[self newCGImageFromCurrentlyProcessedOutput];

NSImage*finalImage =[[NSImage alloc] initWithCGImage:cgImageFromBytes size:NSZeroSize];

CGImageRelease(cgImageFromBytes);returnfinalImage;

}- (NSImage *)imageByFilteringImage:(NSImage *)imageToFilter;

{

CGImageRef image=[self newCGImageByFilteringCGImage:[imageToFilter CGImageForProposedRect:NULL context:[NSGraphicsContext currentContext] hints:nil]];

NSImage*processedImage =[[NSImage alloc] initWithCGImage:image size:NSZeroSize];

CGImageRelease(image);returnprocessedImage;

}- (CGImageRef)newCGImageByFilteringImage:(NSImage *)imageToFilter

{return[self newCGImageByFilteringCGImage:[imageToFilter CGImageForProposedRect:NULL context:[NSGraphicsContext currentContext] hints:nil]];

}#endif#pragmamark -#pragmamarkaccessors

- (void)setAudioEncodingTarget:(GPUImageMovieWriter *)newValue;

{

_audioEncodingTarget=newValue;if( !_audioEncodingTarget.hasAudioTrack )

{

_audioEncodingTarget.hasAudioTrack=YES;

}

}-(void)setOutputTextureOptions:(GPUTextureOptions)outputTextureOptions

{

_outputTextureOptions=outputTextureOptions;if( outputFramebuffer.texture )

{

glBindTexture(GL_TEXTURE_2D, outputFramebuffer.texture);//_outputTextureOptions.format//_outputTextureOptions.internalFormat//_outputTextureOptions.magFilter//_outputTextureOptions.minFilter//_outputTextureOptions.typeglTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_S, _outputTextureOptions.wrapS);

glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_WRAP_T, _outputTextureOptions.wrapT);

glBindTexture(GL_TEXTURE_2D,0);

}

}

@end

 
 
免责声明:本文为网络用户发布,其观点仅代表作者个人观点,与本站无关,本站仅提供信息存储服务。文中陈述内容未经本站证实,其真实性、完整性、及时性本站不作任何保证或承诺,请读者仅作参考,并请自行核实相关内容。
 
© 2005- 王朝網路 版權所有 導航