日韩性视频-久久久蜜桃-www中文字幕-在线中文字幕av-亚洲欧美一区二区三区四区-撸久久-香蕉视频一区-久久无码精品丰满人妻-国产高潮av-激情福利社-日韩av网址大全-国产精品久久999-日本五十路在线-性欧美在线-久久99精品波多结衣一区-男女午夜免费视频-黑人极品ⅴideos精品欧美棵-人人妻人人澡人人爽精品欧美一区-日韩一区在线看-欧美a级在线免费观看

歡迎訪問 生活随笔!

生活随笔

當(dāng)前位置: 首頁 > 编程资源 > 编程问答 >内容正文

编程问答

GPUImage API 文档之GPUImagePicture类

發(fā)布時(shí)間:2025/3/13 编程问答 51 豆豆
生活随笔 收集整理的這篇文章主要介紹了 GPUImage API 文档之GPUImagePicture类 小編覺得挺不錯(cuò)的,現(xiàn)在分享給大家,幫大家做個(gè)參考.

  GPUImagePicture類靜態(tài)圖像處理操作,它可以是需要處理的靜態(tài)圖像,也可以是一張作為紋理使用的圖片,調(diào)用向它發(fā)送processImage消息,進(jìn)行圖像濾鏡處理。

  方法

  -?(id)initWithURL:(NSURL *)url

  說明:使用指定url的圖片來初始化GPUImagePicture

?

  - (id)initWithImage:(UIImage *)newImageSource

  說明:使用指定的UIImage對象來初始化GPUImagePicture

?

  - (id)initWithCGImage:(CGImageRef)newImageSource

  說明:使用指定的CGImageRef對象來初始化GPUImagePicture

?

  - (id)initWithImage:(UIImage *)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput

  說明:使用指定的UIImage對象來初始化GPUImagePicture,是否按比例調(diào)整輸入圖像的尺寸

?

  - (void)processImage

  說明:進(jìn)行圖像處理實(shí)際操作。

?

  - (BOOL)processImageWithCompletionHandler:(void (^)(void))completion

  說明:進(jìn)行圖像處理實(shí)際的操作,completion為當(dāng)處理結(jié)束執(zhí)行的操作。

完整代碼

#import <UIKit/UIKit.h> #import "GPUImageOutput.h"@interface GPUImagePicture : GPUImageOutput {CGSize pixelSizeOfImage;BOOL hasProcessedImage;dispatch_semaphore_t imageUpdateSemaphore; }// Initialization and teardown - (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;// Image rendering - (void)processImage; - (CGSize)outputImageSize;/*** Process image with all targets and filters asynchronously* The completion handler is called after processing finished in the* GPU's dispatch queue - and only if this method did not return NO.** @returns NO if resource is blocked and processing is discarded, YES otherwise*/ - (BOOL)processImageWithCompletionHandler:(void (^)(void))completion; - (void)processImageUpToFilter:(GPUImageOutput<GPUImageInput> *)finalFilterInChain withCompletionHandler:(void (^)(UIImage *processedImage))block;@end #import "GPUImagePicture.h"@implementation GPUImagePicture#pragma mark - #pragma mark Initialization and teardown- (id)initWithURL:(NSURL *)url; {NSData *imageData = [[NSData alloc] initWithContentsOfURL:url];if (!(self = [self initWithData:imageData])){return nil;}return self; }- (id)initWithData:(NSData *)imageData; {UIImage *inputImage = [[UIImage alloc] initWithData:imageData];if (!(self = [self initWithImage:inputImage])){return nil;}return self; }- (id)initWithImage:(UIImage *)newImageSource; {if (!(self = [self initWithImage:newImageSource smoothlyScaleOutput:NO])){return nil;}return self; }- (id)initWithCGImage:(CGImageRef)newImageSource; {if (!(self = [self initWithCGImage:newImageSource smoothlyScaleOutput:NO])){return nil;}return self; }- (id)initWithImage:(UIImage *)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput; {return [self initWithCGImage:[newImageSource CGImage] smoothlyScaleOutput:smoothlyScaleOutput]; }- (id)initWithCGImage:(CGImageRef)newImageSource smoothlyScaleOutput:(BOOL)smoothlyScaleOutput; {if (!(self = [super init])){return nil;}hasProcessedImage = NO;self.shouldSmoothlyScaleOutput = smoothlyScaleOutput;imageUpdateSemaphore = dispatch_semaphore_create(0);dispatch_semaphore_signal(imageUpdateSemaphore);// TODO: Dispatch this whole thing asynchronously to move image loading off main threadCGFloat widthOfImage = CGImageGetWidth(newImageSource);CGFloat heightOfImage = CGImageGetHeight(newImageSource);// If passed an empty image reference, CGContextDrawImage will fail in future versions of the SDK.NSAssert( widthOfImage > 0 && heightOfImage > 0, @"Passed image must not be empty - it should be at least 1px tall and wide");pixelSizeOfImage = CGSizeMake(widthOfImage, heightOfImage);CGSize pixelSizeToUseForTexture = pixelSizeOfImage;BOOL shouldRedrawUsingCoreGraphics = NO;// For now, deal with images larger than the maximum texture size by resizing to be within that limitCGSize scaledImageSizeToFitOnGPU = [GPUImageContext sizeThatFitsWithinATextureForSize:pixelSizeOfImage];if (!CGSizeEqualToSize(scaledImageSizeToFitOnGPU, pixelSizeOfImage)){pixelSizeOfImage = scaledImageSizeToFitOnGPU;pixelSizeToUseForTexture = pixelSizeOfImage;shouldRedrawUsingCoreGraphics = YES;}if (self.shouldSmoothlyScaleOutput){// In order to use mipmaps, you need to provide power-of-two textures, so convert to the next largest power of two and stretch to fillCGFloat powerClosestToWidth = ceil(log2(pixelSizeOfImage.width));CGFloat powerClosestToHeight = ceil(log2(pixelSizeOfImage.height));pixelSizeToUseForTexture = CGSizeMake(pow(2.0, powerClosestToWidth), pow(2.0, powerClosestToHeight));shouldRedrawUsingCoreGraphics = YES;}GLubyte *imageData = NULL;CFDataRef dataFromImageDataProvider = NULL;GLenum format = GL_BGRA;if (!shouldRedrawUsingCoreGraphics) {/* Check that the memory layout is compatible with GL, as we cannot use glPixelStore to* tell GL about the memory layout with GLES.*/if (CGImageGetBytesPerRow(newImageSource) != CGImageGetWidth(newImageSource) * 4 ||CGImageGetBitsPerPixel(newImageSource) != 32 ||CGImageGetBitsPerComponent(newImageSource) != 8){shouldRedrawUsingCoreGraphics = YES;} else {/* Check that the bitmap pixel format is compatible with GL */CGBitmapInfo bitmapInfo = CGImageGetBitmapInfo(newImageSource);if ((bitmapInfo & kCGBitmapFloatComponents) != 0) {/* We don't support float components for use directly in GL */shouldRedrawUsingCoreGraphics = YES;} else {CGBitmapInfo byteOrderInfo = bitmapInfo & kCGBitmapByteOrderMask;if (byteOrderInfo == kCGBitmapByteOrder32Little) {/* Little endian, for alpha-first we can use this bitmap directly in GL */CGImageAlphaInfo alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask;if (alphaInfo != kCGImageAlphaPremultipliedFirst && alphaInfo != kCGImageAlphaFirst &&alphaInfo != kCGImageAlphaNoneSkipFirst) {shouldRedrawUsingCoreGraphics = YES;}} else if (byteOrderInfo == kCGBitmapByteOrderDefault || byteOrderInfo == kCGBitmapByteOrder32Big) {/* Big endian, for alpha-last we can use this bitmap directly in GL */CGImageAlphaInfo alphaInfo = bitmapInfo & kCGBitmapAlphaInfoMask;if (alphaInfo != kCGImageAlphaPremultipliedLast && alphaInfo != kCGImageAlphaLast &&alphaInfo != kCGImageAlphaNoneSkipLast) {shouldRedrawUsingCoreGraphics = YES;} else {/* Can access directly using GL_RGBA pixel format */format = GL_RGBA;}}}}}// CFAbsoluteTime elapsedTime, startTime = CFAbsoluteTimeGetCurrent();if (shouldRedrawUsingCoreGraphics){// For resized or incompatible image: redrawimageData = (GLubyte *) calloc(1, (int)pixelSizeToUseForTexture.width * (int)pixelSizeToUseForTexture.height * 4);CGColorSpaceRef genericRGBColorspace = CGColorSpaceCreateDeviceRGB();CGContextRef imageContext = CGBitmapContextCreate(imageData, (size_t)pixelSizeToUseForTexture.width, (size_t)pixelSizeToUseForTexture.height, 8, (size_t)pixelSizeToUseForTexture.width * 4, genericRGBColorspace, kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);// CGContextSetBlendMode(imageContext, kCGBlendModeCopy); // From Technical Q&A QA1708: http://developer.apple.com/library/ios/#qa/qa1708/_index.htmlCGContextDrawImage(imageContext, CGRectMake(0.0, 0.0, pixelSizeToUseForTexture.width, pixelSizeToUseForTexture.height), newImageSource);CGContextRelease(imageContext);CGColorSpaceRelease(genericRGBColorspace);}else{// Access the raw image bytes directlydataFromImageDataProvider = CGDataProviderCopyData(CGImageGetDataProvider(newImageSource));imageData = (GLubyte *)CFDataGetBytePtr(dataFromImageDataProvider);}// elapsedTime = (CFAbsoluteTimeGetCurrent() - startTime) * 1000.0;// NSLog(@"Core Graphics drawing time: %f", elapsedTime);// CGFloat currentRedTotal = 0.0f, currentGreenTotal = 0.0f, currentBlueTotal = 0.0f, currentAlphaTotal = 0.0f;// NSUInteger totalNumberOfPixels = round(pixelSizeToUseForTexture.width * pixelSizeToUseForTexture.height);//// for (NSUInteger currentPixel = 0; currentPixel < totalNumberOfPixels; currentPixel++)// {// currentBlueTotal += (CGFloat)imageData[(currentPixel * 4)] / 255.0f;// currentGreenTotal += (CGFloat)imageData[(currentPixel * 4) + 1] / 255.0f;// currentRedTotal += (CGFloat)imageData[(currentPixel * 4 + 2)] / 255.0f;// currentAlphaTotal += (CGFloat)imageData[(currentPixel * 4) + 3] / 255.0f;// }//// NSLog(@"Debug, average input image red: %f, green: %f, blue: %f, alpha: %f", currentRedTotal / (CGFloat)totalNumberOfPixels, currentGreenTotal / (CGFloat)totalNumberOfPixels, currentBlueTotal / (CGFloat)totalNumberOfPixels, currentAlphaTotal / (CGFloat)totalNumberOfPixels); runSynchronouslyOnVideoProcessingQueue(^{[GPUImageContext useImageProcessingContext];outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:pixelSizeToUseForTexture onlyTexture:YES];[outputFramebuffer disableReferenceCounting];glBindTexture(GL_TEXTURE_2D, [outputFramebuffer texture]);if (self.shouldSmoothlyScaleOutput){glTexParameteri(GL_TEXTURE_2D, GL_TEXTURE_MIN_FILTER, GL_LINEAR_MIPMAP_LINEAR);}// no need to use self.outputTextureOptions here since pictures need this texture formats and typeglTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)pixelSizeToUseForTexture.width, (int)pixelSizeToUseForTexture.height, 0, format, GL_UNSIGNED_BYTE, imageData);if (self.shouldSmoothlyScaleOutput){glGenerateMipmap(GL_TEXTURE_2D);}glBindTexture(GL_TEXTURE_2D, 0);});if (shouldRedrawUsingCoreGraphics){free(imageData);}else{if (dataFromImageDataProvider){CFRelease(dataFromImageDataProvider);}}return self; }// ARC forbids explicit message send of 'release'; since iOS 6 even for dispatch_release() calls: stripping it out in that case is required. - (void)dealloc; {[outputFramebuffer enableReferenceCounting];[outputFramebuffer unlock];#if !OS_OBJECT_USE_OBJCif (imageUpdateSemaphore != NULL){dispatch_release(imageUpdateSemaphore);} #endif }#pragma mark - #pragma mark Image rendering- (void)removeAllTargets; {[super removeAllTargets];hasProcessedImage = NO; }- (void)processImage; {[self processImageWithCompletionHandler:nil]; }- (BOOL)processImageWithCompletionHandler:(void (^)(void))completion; {hasProcessedImage = YES;// dispatch_semaphore_wait(imageUpdateSemaphore, DISPATCH_TIME_FOREVER);if (dispatch_semaphore_wait(imageUpdateSemaphore, DISPATCH_TIME_NOW) != 0){return NO;}runAsynchronouslyOnVideoProcessingQueue(^{ for (id<GPUImageInput> currentTarget in targets){NSInteger indexOfObject = [targets indexOfObject:currentTarget];NSInteger textureIndexOfTarget = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue];[currentTarget setCurrentlyReceivingMonochromeInput:NO];[currentTarget setInputSize:pixelSizeOfImage atIndex:textureIndexOfTarget];[currentTarget setInputFramebuffer:outputFramebuffer atIndex:textureIndexOfTarget];[currentTarget newFrameReadyAtTime:kCMTimeIndefinite atIndex:textureIndexOfTarget];}dispatch_semaphore_signal(imageUpdateSemaphore);if (completion != nil) {completion();}});return YES; }- (void)processImageUpToFilter:(GPUImageOutput<GPUImageInput> *)finalFilterInChain withCompletionHandler:(void (^)(UIImage *processedImage))block; {[finalFilterInChain useNextFrameForImageCapture];[self processImageWithCompletionHandler:^{UIImage *imageFromFilter = [finalFilterInChain imageFromCurrentFramebuffer];block(imageFromFilter);}]; }- (CGSize)outputImageSize; {return pixelSizeOfImage; }- (void)addTarget:(id<GPUImageInput>)newTarget atTextureLocation:(NSInteger)textureLocation; {[super addTarget:newTarget atTextureLocation:textureLocation];if (hasProcessedImage){[newTarget setInputSize:pixelSizeOfImage atIndex:textureLocation];[newTarget newFrameReadyAtTime:kCMTimeIndefinite atIndex:textureLocation];} }@end

?

轉(zhuǎn)載于:https://www.cnblogs.com/salam/p/4966721.html

總結(jié)

以上是生活随笔為你收集整理的GPUImage API 文档之GPUImagePicture类的全部內(nèi)容,希望文章能夠幫你解決所遇到的問題。

如果覺得生活随笔網(wǎng)站內(nèi)容還不錯(cuò),歡迎將生活随笔推薦給好友。