前言

咱们在前面,首先进行了针对 iOS中的多媒体技能相关几个结构概述:

  1. 进而 用 两篇文章 对 其间的 UIKit相关要害 进行了分述:
  2. 然后咱们 针对 Core Animation结构的要害 进一步打开分述:
  3. 紧接着 咱们快速回忆了 2D绘图引擎Core Graphics结构的要害
  4. 咱们 在此篇文章 ,将 针对 滤镜结构Core Image、GPUImage结构的要害 进一步打开分述:

一、Core Image

Core Image是苹果供给的图画处理结构,首要用于完结图画处理滤镜运用图画剖析等功用。以下是Core Image的中心要害:

1. 首要特点和功用

    1. 滤镜(Filter):
    • Core Image供给了丰厚的滤镜作用,如含糊锐化色彩调整边际检测等。
    • 开发者能够经过Core Image的滤镜功用对图画进行处理和增强。
    • iOS 8 之后 引进 CIFilter,Core Image从此支撑自界说滤镜的创立和运用,完结个性化的图画处理作用。
    1. 图画处理链(Image Processing Pipeline):
    • Core Image运用图画处理链来处理图画,包括输入图画滤镜作用和输出图画
    • 开发者能够构建自界说的图画处理链,完结杂乱的图画处理流程。
    1. 图画剖析(Image Analysis):
    • Core Image支撑图画剖析功用,如人脸检测特征辨认色彩辨认物体辨认等。
    • 开发者能够运用Core Image进行图画剖析,提取图画中的信息和特征
    1. Metal功用优化:
    • Core Image能够与Metal结构结合,运用GPU硬件加速来进步图画处理的功用。
    • 开发者能够经过Metal结构优化Core Image的功用,完结高效的图画处理和滤镜作用。
    1. 图画格局转化(Image Format Conversion):
    • Core Image支撑图画格局的转化和处理,如色彩空间转化像素格局转化等。
    • 开发者能够运用Core Image进行图画格局的转化和处理,满意不同的图画处理需求。
    1. 实时预览(Real-time Preview):
    • Core Image供给实时预览功用,能够在运用程序中实时显现滤镜作用的预览。
    • 开发者能够经过Core Image完结实时的滤镜预览,便利用户调整和检查作用。
    1. 其它
    • Core Image 与 Core Graphics 恰恰相反
      • Core Graphics 用于在运转时创立图画
      • 而 Core Image 是用来处理现已创立的图画的。
    • Core Image 是 iOS5 新加入到 iOS 渠道的一个图画处理结构,供给了强壮高效的图画处理功用, 用来对依据像素的图画进行操作与剖析, 内置了许多强壮的滤镜(Filter) (现在数量超越了180种), 这些Filter 供给了各式各样的作用, 并且还能够经过 滤镜链 将各种作用的 Filter叠加 起来构成强壮的自界说作用。
      • iOS8 之后更是支撑自界说 CIFilter,能够定制满意事务需求的杂乱作用。
    • Core Image 的优点在于十分高效。大部分状况下,它会在 GPU 中完结工作,但假如 GPU 忙,会运用 CPU 进行处理。假如设备支撑 Metal,那么会运用 Metal 处理。这些操作会在底层完结,Apple 的工程师们现已帮助开发者们完结这些操作了。
      • 例如他能够依据需求挑选 CPU 或许 GPU 来处理。
        // 创立依据 CPU 的 CIContext 方针 (默许是依据 GPU,CPU 需求额外设置参数)
        context = [CIContext contextWithOptions: [NSDictionary dictionaryWithObject:[NSNumber numberWithBool:YES] forKey:kCIContextUseSoftwareRenderer]];
        // 创立依据 GPU 的 CIContext 方针
        context = [CIContext contextWithOptions: nil];
        // 创立依据 GPU 的 CIContext 方针
        EAGLContext *eaglctx = [[EAGLContext alloc] initWithAPI:kEAGLRenderingAPIOpenGLES2];
        context = [CIContext contextWithEAGLContext:eaglctx];
      

2. 中心类介绍

    1. CIImage:
    • CIImage是Core Image结构中表明图画数据的类,能够用来表明图画数据源
    • CIImage能够从各种来源创立,如UIImage、CGImage、NSData、图画文件或许像素数据等,用于输入到Core Image的滤镜中进行处理。
    1. CIFilter:
    • CIFilter是Core Image结构中的滤镜类,用于完结各种图画处理和滤镜作用。
    • CIFilter包含了各种内置的滤镜作用,也能够自界说滤镜来完结特定的图画处理需求。
    • 这个结构中对图片特点进行细节处理的类。它对一切的像素进行操作,用一些键-值设置来决议详细操作的程度。
    1. CIContext:
    • CIContext是Core Image结构中的上下文类,用于办理图画处理的环境和输出。
    • CIContext能够指定烘托方针(如屏幕、图画文件)、烘托选项(如色彩空间、缩放份额)等参数。
    1. CIFeature:
    • CIFeature是Core Image结构中的特征类,用于检测图画中的特征和方针。
    • CIFeature能够用于人脸检测、文本辨认、条形码辨认等运用场景。
    1. CIColor:
    • CIColor是Core Image结构中的色彩类,用于表明色彩信息。
    • CIColor能够用来创立色彩方针,设置滤镜作用中的色彩参数。
    1. CIVector:
    • CIVector是Core Image结构中的向量类,用于表明多维向量数据。
    • CIVector能够用来设置滤镜作用中的向量参数,如方位、巨细等。
  • Core Image 的 API 首要便是三类:
    • CIContext 表明上下文,如 Core Graphics 以及 Core Data 中的上下文用于处理制作烘托以及处理保管方针相同,Core Image 的上下文也是完结对图画处理的详细方针。能够从其间取得图片的信息。

3. 代码示例

3.1 滤镜|含糊、锐化、色彩调整、边际检测 和 自界说滤镜

Objective-C示例:

// Objective-C示例:
#import <UIKit/UIKit.h>
#import <CoreImage/CoreImage.h>
// 含糊处理
UIImage *applyBlurFilter(UIImage *image) {
    CIImage *ciImage = [[CIImage alloc] initWithImage:image];
    CIFilter *filter = [CIFilter filterWithName:@"CIGaussianBlur"];
    [filter setValue:ciImage forKey:kCIInputImageKey];
    [filter setValue:@10 forKey:kCIInputRadiusKey];
    CIImage *outputImage = [filter outputImage];
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgImage = [context createCGImage:outputImage fromRect:outputImage.extent];
    UIImage *resultImage = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
    return resultImage;
}
// 锐化处理
UIImage *applySharpenFilter(UIImage *image) {
    CIImage *ciImage = [[CIImage alloc] initWithImage:image];
    CIFilter *filter = [CIFilter filterWithName:@"CISharpenLuminance"];
    [filter setValue:ciImage forKey:kCIInputImageKey];
    [filter setValue:@0.5 forKey:kCIInputSharpnessKey];
    CIImage *outputImage = [filter outputImage];
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgImage = [context createCGImage:outputImage fromRect:outputImage.extent];
    UIImage *resultImage = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
    return resultImage;
}
// 色彩调整
UIImage *applyColorAdjustmentFilter(UIImage *image) {
    CIImage *ciImage = [[CIImage alloc] initWithImage:image];
    CIFilter *filter = [CIFilter filterWithName:@"CIColorControls"];
    [filter setValue:ciImage forKey:kCIInputImageKey];
    [filter setValue:@1.2 forKey:kCIInputContrastKey];
    [filter setValue:@0.5 forKey:kCIInputBrightnessKey];
    [filter setValue:@0.8 forKey:kCIInputSaturationKey];
    CIImage *outputImage = [filter outputImage];
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgImage = [context createCGImage:outputImage fromRect:outputImage.extent];
    UIImage *resultImage = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
    return resultImage;
}
// 边际检测
UIImage *applyEdgeDetectionFilter(UIImage *image) {
    CIImage *ciImage = [[CIImage alloc] initWithImage:image];
    CIFilter *filter = [CIFilter filterWithName:@"CIEdges"];
    [filter setValue:ciImage forKey:kCIInputImageKey];
    CIImage *outputImage = [filter outputImage];
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgImage = [context createCGImage:outputImage fromRect:outputImage.extent];
    UIImage *resultImage = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
    return resultImage;
}
// 自界说滤镜
UIImage *applyCustomFilter(UIImage *image) {
    CIImage *ciImage = [[CIImage alloc] initWithImage:image];
    // 自界说滤镜
    CIFilter *filter = [CIFilter filterWithName:@"CIColorMatrix"];
    [filter setValue:ciImage forKey:kCIInputImageKey];
    // 设置自界说参数
    CIVector *RVector = [CIVector vectorWithX:1 Y:0 Z:0 W:0];
    CIVector *GVector = [CIVector vectorWithX:0 Y:1 Z:0 W:0];
    CIVector *BVector = [CIVector vectorWithX:0 Y:0 Z:1 W:0];
    CIVector *AVector = [CIVector vectorWithX:0 Y:0 Z:0 W:1];
    [filter setValue:RVector forKey:@"inputRVector"];
    [filter setValue:GVector forKey:@"inputGVector"];
    [filter setValue:BVector forKey:@"inputBVector"];
    [filter setValue:AVector forKey:@"inputAVector"];
    CIImage *outputImage = [filter outputImage];
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgImage = [context createCGImage:outputImage fromRect:outputImage.extent];
    UIImage *resultImage = [UIImage imageWithCGImage

Swift示例:

import UIKit
import CoreImage
// 图画处理类
class ImageProcessor {
    // 运用含糊滤镜
    func applyBlurFilter(to image: UIImage) -> UIImage? {
        if let ciImage = CIImage(image: image) {
            let filter = CIFilter(name: "CIGaussianBlur")
            filter?.setValue(ciImage, forKey: kCIInputImageKey)
            filter?.setValue(5.0, forKey: kCIInputRadiusKey)
            if let outputImage = filter?.outputImage {
                let context = CIContext()
                if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
                    return UIImage(cgImage: cgImage)
                }
            }
        }
        return nil
    }
    // 运用锐化滤镜
    func applySharpenFilter(to image: UIImage) -> UIImage? {
        if let ciImage = CIImage(image: image) {
            let filter = CIFilter(name: "CISharpenLuminance")
            filter?.setValue(ciImage, forKey: kCIInputImageKey)
            filter?.setValue(0.5, forKey: kCIInputSharpnessKey)
            if let outputImage = filter?.outputImage {
                let context = CIContext()
                if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
                    return UIImage(cgImage: cgImage)
                }
            }
        }
        return nil
    }
    // 运用色彩调整滤镜
    func applyColorAdjustmentFilter(to image: UIImage) -> UIImage? {
        if let ciImage = CIImage(image: image) {
            let filter = CIFilter(name: "CIColorControls")
            filter?.setValue(ciImage, forKey: kCIInputImageKey)
            filter?.setValue(1.2, forKey: kCIInputContrastKey)
            filter?.setValue(0.8, forKey: kCIInputBrightnessKey)
            filter?.setValue(0.5, forKey: kCIInputSaturationKey)
            if let outputImage = filter?.outputImage {
                let context = CIContext()
                if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
                    return UIImage(cgImage: cgImage)
                }
            }
        }
        return nil
    }
    // 运用边际检测滤镜
    func applyEdgeDetectionFilter(to image: UIImage) -> UIImage? {
        if let ciImage = CIImage(image: image) {
            let filter = CIFilter(name: "CIEdges")
            filter?.setValue(ciImage, forKey: kCIInputImageKey)
            if let outputImage = filter?.outputImage {
                let context = CIContext()
                if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
                    return UIImage(cgImage: cgImage)
                }
            }
        }
        return nil
    }
    // 运用自界说滤镜
    func applyCustomFilter(to image: UIImage) -> UIImage? {
        if let ciImage = CIImage(image: image) {
            // 自界说滤镜:将图画转为灰度图
            let filter = CIFilter(name: "CIPhotoEffectMono")
            filter?.setValue(ciImage, forKey: kCIInputImageKey)
            if let outputImage = filter?.outputImage {
                let context = CIContext()
                if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
                    return UIImage(cgImage: cgImage)
                }
            }
        }
        return nil
    }
}
// 运用示例
let image = UIImage(named: "example.jpg")!
let processor = ImageProcessor()
let blurredImage = processor.applyBlurFilter(to: image)
let sharpenedImage = processor.applySharpenFilter(to: image)
let colorAdjustedImage = processor.applyColorAdjustmentFilter(to: image)
let edgeDetectedImage = processor.applyEdgeDetectionFilter(to: image)
let customFilteredImage = processor.applyCustomFilter(to: image)

3.1 图画处理链|输入图画、滤镜作用、和输出图画

Objective-C示例:

// Objective-C示例:
#import <UIKit/UIKit.h>
#import <CoreImage/CoreImage.h>
UIImage *applyFilterToImage(UIImage *inputImage) {
    CIImage *ciImage = [[CIImage alloc] initWithImage:inputImage];
    CIFilter *filter = [CIFilter filterWithName:@"CIPhotoEffectMono"];
    [filter setValue:ciImage forKey:kCIInputImageKey];
    CIImage *outputImage = [filter outputImage];
    CIContext *context = [CIContext contextWithOptions:nil];
    CGImageRef cgImage = [context createCGImage:outputImage fromRect:outputImage.extent];
    UIImage *filteredImage = [UIImage imageWithCGImage:cgImage];
    CGImageRelease(cgImage);
    return filteredImage;
}

Swift示例:

// Swift示例:
import UIKit
import CoreImage
func applyFilterToImage(inputImage: UIImage) -> UIImage? {
    if let ciImage = CIImage(image: inputImage) {
        let filter = CIFilter(name: "CIPhotoEffectMono")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        if let outputImage = filter?.outputImage {
            let context = CIContext(options: nil)
            if let cgImage = context.createCGImage(outputImage, from: outputImage.extent) {
                let filteredImage = UIImage(cgImage: cgImage)
                return filteredImage
            }
        }
    }
    return nil
}

3.1 图画剖析|人脸检测、特征辨认、色彩辨认、物体辨认

Objective-C示例:

// Objective-C示例:
#import <UIKit/UIKit.h>
#import <CoreImage/CoreImage.h>
- (void)analyzeImage:(UIImage *)image {
    CIImage *ciImage = [[CIImage alloc] initWithImage:image];
    // 人脸检测
    NSDictionary *options = @{CIDetectorAccuracy: CIDetectorAccuracyHigh};
    CIDetector *faceDetector = [CIDetector detectorOfType:CIDetectorTypeFace context:nil options:options];
    NSArray *faces = [faceDetector featuresInImage:ciImage];
    for (CIFaceFeature *faceFeature in faces) {
        NSLog(@"Detected face at %@", NSStringFromCGRect(faceFeature.bounds));
    }
    // 特征辨认
    NSDictionary *featureOptions = @{CIDetectorImageOrientation: @(1)};
    CIDetector *featureDetector = [CIDetector detectorOfType:CIDetectorTypeQRCode context:nil options:featureOptions];
    NSArray *features = [featureDetector featuresInImage:ciImage];
    for (CIQRCodeFeature *feature in features) {
        NSLog(@"Detected QR code with message: %@", feature.messageString);
    }
    // 色彩辨认
    CIColor *averageColor = [ciImage valueForKey:@"inputImage"];
    NSLog(@"Average color of the image: %@", averageColor);
    // 物体辨认
    NSDictionary *objectOptions = @{CIDetectorAccuracy: CIDetectorAccuracyHigh};
    CIDetector *objectDetector = [CIDetector detectorOfType:CIDetectorTypeRectangle context:nil options:objectOptions];
    NSArray *objects = [objectDetector featuresInImage:ciImage];
    for (CIRectangleFeature *objectFeature in objects) {
        NSLog(@"Detected object at %@", NSStringFromCGRect(objectFeature.bounds));
    }
}

Swift示例:

import UIKit
import CoreImage
class ImageAnalysis {
    func analyzeImage(image: UIImage) {
        if let ciImage = CIImage(image: image) {
            let context = CIContext()
            // 人脸检测
            let faceDetector = CIDetector(ofType: CIDetectorTypeFace, context: context, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])
            let faces = faceDetector?.features(in: ciImage)
            for face in faces as! [CIFaceFeature] {
                print("Face bounds: (face.bounds)")
                if face.hasLeftEyePosition {
                    print("Left eye position: (face.leftEyePosition)")
                }
                if face.hasRightEyePosition {
                    print("Right eye position: (face.rightEyePosition)")
                }
            }
            // 特征辨认
            let featureDetector = CIDetector(ofType: CIDetectorTypeRectangle, context: context, options: [CIDetectorAccuracy: CIDetectorAccuracyHigh])
            let features = featureDetector?.features(in: ciImage)
            for feature in features as! [CIRectangleFeature] {
                print("Feature bounds: (feature.bounds)")
            }
            // 色彩辨认
            let colorDetector = CIDetector(ofType: CIDetectorTypeColor, context: context, options: nil)
            let colors = colorDetector?.features(in: ciImage)
            for color in colors as! [CIColorFeature] {
                print("Detected color: (color.color)")
            }
            // 物体辨认
            let objectDetector = CIDetector(ofType: CIDetectorTypeQRCode, context: context, options: nil)
            let objects = objectDetector?.features(in: ciImage)
            for object in objects as! [CIQRCodeFeature] {
                print("Detected QR code: (object.messageString ?? "")")
            }
        }
    }
}
// 运用示例
let image = UIImage(named: "sampleImage")
let imageAnalysis = ImageAnalysis()
imageAnalysis.analyzeImage(image: image)

3.1 Metal功用优化

Objective-C示例:

// Objective-C示例:
#import <Metal/Metal.h>
#import <MetalKit/MetalKit.h>
#import <CoreImage/CoreImage.h>
// 创立Metal设备和CIContext
id<MTLDevice> device = MTLCreateSystemDefaultDevice();
CIContext *ciContext = [CIContext contextWithMTLDevice:device];
// 创立Metal纹路
MTKView *metalView = [[MTKView alloc] initWithFrame:CGRectZero device:device];
id<MTLTexture> metalTexture = metalView.currentDrawable.texture;
// 创立CIImage
CIImage *ciImage = [CIImage imageWithMTLTexture:metalTexture options:nil];
// 创立滤镜
CIFilter *filter = [CIFilter filterWithName:@"CIColorControls"];
[filter setValue:ciImage forKey:kCIInputImageKey];
[filter setValue:@(1.2) forKey:kCIInputContrastKey];
// 烘托并显现成果
CIImage *outputImage = [filter outputImage];
[ciContext render:outputImage toMTLTexture:metalTexture commandBuffer:nil bounds:outputImage.extent colorSpace:outputImage.colorSpace];

Swift示例:

// Swift示例:
import Metal
import MetalKit
import CoreImage
// 创立Metal设备和CIContext
let device = MTLCreateSystemDefaultDevice()
let ciContext = CIContext(mtlDevice: device!)
// 创立Metal纹路
let metalView = MTKView(frame: CGRect.zero, device: device)
let metalTexture = metalView.currentDrawable?.texture
// 创立CIImage
let ciImage = CIImage(mtlTexture: metalTexture!, options: nil)
// 创立滤镜
let filter = CIFilter(name: "CIColorControls")
filter?.setValue(ciImage, forKey: kCIInputImageKey)
filter?.setValue(1.2, forKey: kCIInputContrastKey)
// 烘托并显现成果
if let outputImage = filter?.outputImage {
    ciContext.render(outputImage, to: metalTexture!, commandBuffer: nil, bounds: outputImage.extent, colorSpace: outputImage.colorSpace)
}

3.1 实时预览

Objective-C示例:

// Objective-C示例:
#import <UIKit/UIKit.h>
#import <CoreImage/CoreImage.h>
@interface ViewController : UIViewController <AVCaptureVideoDataOutputSampleBufferDelegate>
@property (nonatomic, strong) AVCaptureSession *captureSession;
@property (nonatomic, strong) AVCaptureVideoPreviewLayer *previewLayer;
@property (nonatomic, strong) CIContext *ciContext;
@end
@implementation ViewController
- (void)viewDidLoad {
    [super viewDidLoad];
    self.captureSession = [[AVCaptureSession alloc] init];
    AVCaptureDevice *videoDevice = [AVCaptureDevice defaultDeviceWithMediaType:AVMediaTypeVideo];
    NSError *error = nil;
    AVCaptureDeviceInput *videoInput = [AVCaptureDeviceInput deviceInputWithDevice:videoDevice error:&error];
    if (videoInput) {
        [self.captureSession addInput:videoInput];
        AVCaptureVideoDataOutput *videoOutput = [[AVCaptureVideoDataOutput alloc] init];
        [videoOutput setSampleBufferDelegate:self queue:dispatch_get_main_queue()];
        [self.captureSession addOutput:videoOutput];
        self.previewLayer = [AVCaptureVideoPreviewLayer layerWithSession:self.captureSession];
        self.previewLayer.frame = self.view.bounds;
        [self.view.layer addSublayer:self.previewLayer];
        [self.captureSession startRunning];
        self.ciContext = [CIContext contextWithOptions:nil];
    } else {
        NSLog(@"Error setting up video input: %@", error);
    }
}
- (void)captureOutput:(AVCaptureOutput *)output didOutputSampleBuffer:(CMSampleBufferRef)sampleBuffer fromConnection:(AVCaptureConnection *)connection {
    CVPixelBufferRef pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer);
    CIImage *ciImage = [CIImage imageWithCVPixelBuffer:pixelBuffer];
    // 运用滤镜
    CIFilter *filter = [CIFilter filterWithName:@"CIColorControls"];
    [filter setValue:ciImage forKey:kCIInputImageKey];
    [filter setValue:@(1.2) forKey:kCIInputContrastKey];
    CIImage *outputImage = [filter outputImage];
    // 烘托到预览层
    [self.ciContext render:outputImage toCVPixelBuffer:pixelBuffer];
}
@end

Swift示例:

// Swift示例:
import UIKit
import AVFoundation
class ViewController: UIViewController, AVCaptureVideoDataOutputSampleBufferDelegate {
    var captureSession: AVCaptureSession!
    var previewLayer: AVCaptureVideoPreviewLayer!
    var ciContext: CIContext!
    override func viewDidLoad() {
        super.viewDidLoad()
        captureSession = AVCaptureSession()
        guard let videoDevice = AVCaptureDevice.default(for: .video),
              let videoInput = try? AVCaptureDeviceInput(device: videoDevice) else {
            return
        }
        if captureSession.canAddInput(videoInput) {
            captureSession.addInput(videoInput)
            let videoOutput = AVCaptureVideoDataOutput()
            videoOutput.setSampleBufferDelegate(self, queue: DispatchQueue.main)
            captureSession.addOutput(videoOutput)
            previewLayer = AVCaptureVideoPreviewLayer(session: captureSession)
            previewLayer.frame = view.bounds
            view.layer.addSublayer(previewLayer)
            captureSession.startRunning()
            ciContext = CIContext()
        }
    }
    func captureOutput(_ output: AVCaptureOutput, didOutput sampleBuffer: CMSampleBuffer, from connection: AVCaptureConnection) {
        guard let pixelBuffer = CMSampleBufferGetImageBuffer(sampleBuffer) else { return }
        let ciImage = CIImage(cvPixelBuffer: pixelBuffer)
        // 运用滤镜
        let filter = CIFilter(name: "CIColorControls")
        filter?.setValue(ciImage, forKey: kCIInputImageKey)
        filter?.setValue(1.2, forKey: kCIInputContrastKey)
        if let outputImage = filter?.outputImage {
            // 烘托到预览层
            ciContext.render(outputImage, to: pixelBuffer)
        }
    }
}

4. 总结

Core Image的图画剖析功用比较鸡肋,且滤镜功用比较关闭。咱们在日常开发中一般用GPUImage较多.因而在这儿只做基本了解.

相对 Core Image有更深的认识和实践,引荐几篇文章:

二、GPUImage

1. 简介

GPUImage是一个依据OpenGL ES 2.0的开源的图画处理库,作者是Brad LarsonGPUImageOpenGL ES封装为简练的Objective-CSwift接口,能够用来给图画、实时相机视频、电影等增加滤镜。

现在GPUImage有三个版别:

本文 首要针对 GPUImage1打开介绍。GPUImage2、GPUImage3与GPUImage1迥然不同。

2. 与Core Image差异

关于图画的处理苹果官方供给了Core Image结构,那么GPUImage和Core Image有哪些差异呢?

2.1 GPUImage

  • 最低支撑iOS 4.0,iOS 5.0之后就支撑自界说滤镜
  • 在低端机型上,GPUImage有更高的体现
  • GPUImage 在视频处理上有更好的体现.
  • GPUImage 代码彻底开源,完结通明.
  • 能够依据自己的事务需求,定制愈加杂乱的管线操作.可定制程度高.
  • GPUImage当处理超越纹路约束的图画的时分,会先做判别,压缩成最大纹路约束的图画,导致图画质量损失

2.2 Core Image

  • 官方结构,运用放心,维护便利.
  • 支撑CPU烘托,能够在后台继续处理和保存图片.
  • 支撑运用Metal烘托图画,而Metal在iOS 渠道上有更好的体现.
  • 一些滤镜的功用更强劲,例如由Metal Performance Shaders支撑的含糊滤镜等
  • Metal,SpriteKit,Core Animation 等更完美的配合.
  • 支撑图画辨认功用.包括人脸辨认,条形码辨认,文本辨认等.
  • 支撑主动增强图画作用,会剖析图画的直方图,图画特点,脸部区域,然后经过一组滤镜来改进图画作用.
  • 支撑对原生RAW格局图片的处理.
  • 滤镜链的功用比GPUImage高.
  • 支撑对大图进行处理,超越GPU纹路约束4096 * 4096的时分,会主动拆分成几个小块处理(Automatic tiling).
    • GPUImage对大图的处理方案则是压缩图片到最大纹路约束,会导致图画质量损失.

3. GPUImage特性

  • 丰厚的输入组件摄像头、图片、视频、OpenGL纹路、二进制数据、UIElement (UIView, CALayer)
  • 大量现成的内置滤镜(4大类)
    1. 色彩类(亮度、色度、饱满度、对比度、曲线、白平衡..)
    2. 图画类(仿射改换、裁剪、高斯含糊、毛玻璃作用..)
    3. 色彩混合类(差异混合、alpha混合、遮罩混合..)
    4. 作用类(像素化、素描作用、压花作用、球形玻璃作用..)
  • 丰厚的输出组件UIView 、视频文件、GPU纹路、二进制数据
  • 活络的滤镜链滤镜作用之间能够彼此串联、并联,调用办理适当活络。
  • 接口易用,滤镜和OpenGL资源的创立及运用都做了统一的封装,简略易用,并且内置了一个cache模块完结了framebuffer 的复用。
  • 线程办理OpenGLContext不是多线程安全的, GPUImage创立了专的contextQueue,一切的滤镜都会扔到统一的线程中处理。
  • 轻松完结自界说滤镜作用承继GPUImageFilter主动取得上面悉数特性,无需重视上下文的环境树立,专心于作用的中心算法完结即可。

4. 运用流程|滤镜链介绍

在 GPUImage 中,对图画数据的处理都是经过树立滤镜链来完结的。

这儿就触及到了一个类 GPUImageOutput 和一个协议 GPUImageInput

  • 关于承继了 GPUImageOutput 的类,能够理解为具有输出图画数据的才干;
  • 关于完结了 GPUImageInput 协议的类,能够理解为具有接纳图画数据输入的才干。
  • 顾名思义,滤镜链作为一个链路,具有起点、中心节点和结尾。依据前面的描绘,
    • 滤镜链的起点应该只承继了 GPUImageOutput 类,
    • 滤镜链的结尾应该只完结了 GPUImageInput 协议
    • 而关于中心的结点应该一同承继了 GPUImageOutput 类并完结了 GPUImageInput 协议,这样才具有承上启下的作用。

GPUImage的运用首要分为三部分:

  1. 滤镜链起点: 输入数据
  2. 滤镜: 处理数据
  3. 滤镜链结尾: 输出数据

4.1 滤镜链起点

在 GPUImage 中,只承继了GPUImageOutput,而没有完结GPUImageInput协议的类有六个,也便是说有六种类型的输入源:

  1. GPUImagePicture:
    用来处理静态图片。本质解压图片->纹路->用滤镜来进行处理.
    GPUImagePicture经过图片来初始化,本质上是先将图片转化为CGImageRef,然后将CGImageRef转化为纹路。

  2. GPUImageRawDataInput:
    二进制数据->纹路图片. CVPixelFormat
    GPUImageRawDataInput经过二进制数据初始化,然后将二进制数据转化为纹路,在初始化的时分需求指明数据的格局(GPUPixelFormat)。

  3. GPUImageTextureInput:
    用纹路数据.
    GPUImageTextureInput经过现已存在的纹路来初始化。已然纹路现已存在,在初始化的时分就不会从头去生成,仅仅将纹路的索引保存下来

  4. GPUImageUIElement:
    UIView/CAL ayer ->图画数据->纹路.
    GPUImageUIElement 能够经过 UIView 或许 CALayer 来初始化,终究都是调用 CALayerrenderInContext: 办法,将当时显现的内容制作到 CoreGraphics 的上下文中,然后获取图画数据。然后将数据转化为纹路。简略来说便是截屏,截取当时控件的内容。

    这个类能够用来完结在视频上增加文字水印的功用。因为在 OpenGL 中不能直接进行文本的制作,所以假如咱们想把一个 UILabel 的内容增加到滤镜链里边去,运用 GPUImageUIElement 来完结是很适宜的。

  5. GPUImageMovie:
    视频文件-> AVAssetReader -> 逐帧读取视频->帧数据转化成纹路->滤镜处理.AVAssetReader0utput -> CMSamplerBufferRef -> CVImageBufferRef ->CVOpenGLESTextureRef -> Texture
    GPUImageMovie 经过本地的视频来初始化。首先经过 AVAssetReader 来逐帧读取视频,然后将帧数据转化为纹路,详细的流程大概是:AVAssetReaderOutput -> CMSampleBufferRef -> CVImageBufferRef -> CVOpenGLESTextureRef -> Texture

  6. GPUImageVideoCamera:
    依据AVFundation -> didoutPutSampleBuffer
    GPUImageVideoCamera 经过相机参数来初始化,经过屏幕份额相机方位(前后置) 来初始化相机。
    这儿首要运用 AVCaptureVideoDataOutput 来获取继续的视频流数据输出,在代理办法 captureOutput:didOutputSampleBuffer:fromConnection: 中能够拿到 CMSampleBufferRef ,将其转化为纹路的进程与 GPUImageMovie 相似。

  7. 子类(GPUImageStillCamera)
    咱们在项目中运用的是它的子类 GPUImageStillCamera
    GPUImageStillCamera 在原来的根底上多了一个 AVCaptureStillImageOutput,它是咱们完结摄影功用的要害,在 captureStillImageAsynchronouslyFromConnection:completionHandler: 办法的回调中,相同能拿到咱们熟悉 CMSampleBufferRef

简略来说,GPUImageVideoCamera只能录制视频,GPUImageStillCamera还能够摄影, 因而咱们运用GPUImageStillCamera

4.2 滤镜(GPUImageFilter及其子类)

基类:GPUImageFilter

  • 滤镜链的要害角色是GPUImageFilter,它一同承继了GPUImageOutput类并完结了GPUImageInput协议。GPUImageFilter完结承上启下功用的根底是「烘托到纹路」
  • 现在GPUImage大概有200多个滤镜,这儿不逐个赘述.
  • 假如需求自界说滤镜,只需求一个承继于GPUImageFilter.并依据需求修正上色器程序即可.
  • GPUImage库中供给的大部分滤镜都是经过片元上色器的一系列操作来完结相应的作用
  • 大部分滤镜都是对图片中的像素进行核算产生新的像素色彩处理
  • 滤镜处理的原理:
    静态图片或许视频的每一帧进行图形改换后再显现到屏幕上,其本质便是像素点的方位和色彩的改动
  • 每一个滤镜都能把输出的纹路能够作为下一个滤镜的输入,完结多层滤镜作用的叠加(多层滤镜处理)

4.3 滤镜结尾

  1. GPUImageMoviewWriter: AVAssetWriter把每-帧纹路的数据从帧缓存区->指定文件.
  2. GPUImageRawData0utput: 处理滤镜帧缓存区的二进制数据
  3. GPUImageTextureOutput
  4. GPUlmageView

在 GPUImage 中,完结了 GPUImageInput 协议,而没有承继 GPUImageOutput 的类有四个:

  • 1、GPUImageMovieWriter
    GPUImageMovieWriter 封装了 AVAssetWriter,能够逐帧从帧缓存的烘托成果中读取数据,终究经过 AVAssetWriter 将视频文件保存到指定的路径。
  • 2、GPUImageRawDataOutput
    GPUImageRawDataOutput 经过 rawBytesForImage 特点,能够获取到当时输入纹路的二进制数据。
    假定咱们的滤镜链在输入源和结尾之间,连接了三个滤镜,而咱们需求拿到第二个滤镜烘托后的数据,用来做人脸辨认。那咱们能够在第二个滤镜后边再增加一个 GPUImageRawDataOutput 作为输出,则能够拿到对应的二进制数据,且不会影响原来的烘托流程。
  • 3、GPUImageTextureOutput
    这个类的完结十分简略,供给协议办法 newFrameReadyFromTextureOutput:,在每一帧烘托完毕后,将自身返回,经过 texture 特点就能够拿到输入纹路的索引。
  • 4、GPUImageView
    GPUImageView 承继自 UIView,经过输入的纹路,履行一遍烘托流程。这次的烘托方针不是新的纹路,而是自身的 layer

这个类是咱们完结相机功用的重要组成部分,咱们一切的滤镜作用,都要依靠它来出现。

5. 结构解析

  • GPUImage结构选用的链式( Chain )结构.
    • 首要有一个GPUImageoutput interfaceGPUImageInput protocol 串联起来.
  • GPUImageOutput担任输出纹路Texture ;
  • GPUImageInput担任输入纹路Texture ;

整个链式图画数据进程,纹路作为中心载体.

  • 当然GPUImage不仅仅适用于静态图片,还适用视频、实时拍摄等,这些不同的载体都是承继于GPUImageOutput类。
  • 基本上每一个滤镜都是承继自GPUImageFilter,而GPUImageFilter是整套结构的中心
    • GPUImageFilter接纳一个GPUImageFrameBuffer输入,调用GLProgram烘托处理之后,输出一个GPUImageFrameBuffer
    • 再把输出的GPUImageFrameBuffer传给经过targets特点关联的下一级滤镜,直到传递给终究的输出组件。

6. 源码结构剖析

07-iOS 多媒体技能| 滤镜结构Core Image、GPUImage要害回忆【滤镜链、内置滤镜、自界说滤镜、GPUImage的简略运用等】
07-iOS 多媒体技能| 滤镜结构Core Image、GPUImage要害回忆【滤镜链、内置滤镜、自界说滤镜、GPUImage的简略运用等】

7. 内置滤镜介绍

现在GPUImage内置了125滤镜,分为以下几类:

7.1 色彩调整

  • GPUImageBrightnessFilter: 调整图画的亮度

    • brightness:调整后的亮度(-1.0 – 1.0,默许为 0.0)
  • GPUImageExposureFilter: 调整图画的曝光

    • exposure:调整后的曝光(-10.0 – 10.0,默许为 0.0)
  • GPUImageContrastFilter: 调整图画的对比度

    • contrast:调整后的对比度(0.0 – 4.0,默许为 1.0)
  • GPUImageSaturationFilter:调整图画的饱满度

    • 饱满度:运用于图画的饱满度或去饱满度(0.0 – 2.0,默许值为 1.0)
  • GPUImageGammaFilter:调整图画的伽玛

    • gamma:要运用的 gamma 调整(0.0 – 3.0,默许值为 1.0)
  • GPUImageLevelsFilter:相似 Photoshop 的等级调整。min、max、minOut 和 maxOut 参数是 [0, 1] 规模内的浮点数。假如 Photoshop 的参数在 [0, 255] 规模内,则必须先将它们转化为 [0, 1]。gamma/mid 参数是一个 >= 0 的浮点数。这与来自 Photoshop 的值相匹配。假如您想将等级运用到 RGB 以及单个通道,您需求运用此过滤器两​​次 – 首先是单个通道,然后是一切通道。

  • GPUImageColorMatrixFilter:经过对图画运用矩阵来转化图画的色彩

    • colorMatrix:一个 4×4 矩阵,用于转化图画中的每种色彩 – intensity:新改换的色彩替换每个像素的原始色彩的程度
  • GPUImageRGBFilter:调整图画的各个 RGB 通道

    • red:每个色彩通道乘以的归一化值。规模从 0.0 开端,默许值为 1.0。 – 绿色: – 蓝色
  • GPUImageHueFilter:调整图画的色彩

    • 色彩:色彩视点,以度为单位。默许90度
  • GPUImageVibranceFilter:调整图画的振动

    • vibrance:要运用的 vibrance 调整,运用 0.0 作为默许值,主张的最小值/最大值别离约为 -1.2 和 1.2。
  • GPUImageWhiteBalanceFilter:调整图画的白平衡。

    • temperature:调整图画的温度,以K为单位。值 4000 十分凉爽,7000 十分温暖。默许值为 5000。请注意,4000 到 5000 之间的份额在视觉上几乎与 5000 到 7000 之间的份额相同重要。 – tint:调整图画的色彩。值 -200十分绿,200十分粉赤色。默许值为 0。
  • GPUImageToneCurveFilter:依据每个色彩通道的样条曲线调整图画的色彩。

    • 赤色控制点: – 绿色控制点: – 蓝色控制点: – rgbCompositeControlPoints:色彩曲线选用一系列控制点,这些控制点为每个色彩重量或合成中的一切三个重量界说样条曲线。它们在 NSArray 中存储为 NSValue-wrapped CGPoints,具有从 0 – 1 的标准化 X 和 Y 坐标。默许值为 (0,0)、(0.5,0.5)、(1,1)。
  • GPUImageHighlightShadowFilter:调整图画的暗影和高光

    • shadows:增加以减轻暗影,从 0.0 到 1.0,默许值为 0.0。 – highlights:从 1.0 到 0.0 减少以加深高光,默许值为 1.0。
  • GPUImageHighlightShadowTintFilter:答应您运用色彩和强度独立地为图画的暗影和高光上色

    • shadowTintColor:暗影色彩 RGB 色彩 (GPUVector4)。默许值:({1.0f, 0.0f, 0.0f, 1.0f}赤色)。 – highlightTintColor:杰出显现色彩 RGB 色彩 (GPUVector4)。默许值:({0.0f, 0.0f, 1.0f, 1.0f}蓝色)。 – shadowTintIntensity:暗影色彩强度,从 0.0 到 1.0。默许值:0.0 – highlightTintIntensity:杰出显现色彩强度,从 0.0 到 1.0,默许值为 0.0。
  • GPUImageLookupFilter:运用 RGB 色彩查找图画从头映射图画中的色彩。首先,运用您最喜欢的相片编辑运用程序对来自 GPUImage/framework/Resources 的 lookup.png 运用过滤器。为了使其正常工作,每个像素色彩不得依赖于其他像素(例如,含糊将不起作用)。假如您需求更杂乱的过滤器,您能够依据需求创立尽或许多的查找表。准备就绪后,运用新的 lookup.png 文件作为 GPUImageLookupFilter 的第二个输入。

  • GPUImageAmatorkaFilter:依据 Amatorka 的 Photoshop 动作的相片滤镜:http://amatorka.deviantart.com/art/Amatorka-Action-2-121069631。假如您想运用此作用,您必须将 GPUImage Resources 文件夹中的 lookup_amatorka.png 增加到您的运用程序包中。

  • GPUImageMissEtikateFilter:依据 Miss Etikate 的 Photoshop 动作的相片滤镜:http://miss-etikate.deviantart.com/art/Photoshop-Action-15-120151961。假如您想运用此作用,您必须将 GPUImage Resources 文件夹中的 lookup_miss_etikate.png 增加到您的运用程序包中。

  • GPUImageSoftEleganceFilter:另一个依据查找的色彩重映射过滤器。假如您想运用此作用,您必须将 GPUImage Resources 文件夹中的 lookup_soft_elegance_1.png 和 lookup_soft_elegance_2.png 增加到您的运用程序包中。

  • GPUImageSkinToneFilter:一种肤色彩整滤镜,可影响独特的浅肤色规模,并相应地调整粉赤色/绿色或粉赤色/橙色规模。默许值针对白种人皮肤,但能够依据需求进行调整。

    • skinToneAdjust:调整肤色的量。默许值:0.0,主张的最小值/最大值:别离为 -0.3 和 0.3。 – skinHue:要检测的肤色。默许值:0.05(白种人至微红皮肤)。 – skinHueThreshold:肤色的改动量。默许值:40.0。 – maxHueShift:答应的最大色彩偏移量。默许值:0.25。 – maxSaturationShift= 要移动的最大饱满度(运用橙色时)。默许值:0.4。 – upperSkinToneColor=GPUImageSkinToneUpperColorGreenGPUImageSkinToneUpperColorOrange
  • GPUImageColorInvertFilter:回转图画的色彩

  • GPUImageGrayscaleFilter:将图画转化为灰度(饱满度过滤器的完结速度稍快,但无法改动色彩奉献)

  • GPUImageMonochromeFilter:依据每个像素的亮度将图画转化为单色版别

    • intensity: 特定色彩代替正常图画色彩的程度(0.0 – 1.0,默许为 1.0) – color:用作作用根底的色彩,默许值为 (0.6, 0.45, 0.3, 1.0)。
  • GPUImageFalseColorFilter:运用图画的亮度在两种用户指定的色彩之间进行混合

    • firstColor:第一种和第二种色彩别离指定用什么色彩替换图画的暗区和亮区。默许值是 (0.0, 0.0, 0.5) 和 (1.0, 0.0, 0.0)。 – 第二色彩
  • GPUImageHazeFilter:用于增加或去除雾度(相似于 UV 过滤器)

    • distance: 运用色彩的强度。默许值 0。最佳值介于 -.3 和 .3 之间。 – 斜率:色彩改动量。默许值 0。最佳值介于 -.3 和 .3 之间。
  • GPUImageSepiaFilter: 简略的棕褐色彩滤镜

    • intensity:棕褐色彩替换正常图画色彩的程度(0.0 – 1.0,默许值为 1.0)
  • GPUImageOpacityFilter:调整传入图画的 alpha 通道

    • 不通明度:将每个像素的传入 alpha 通道乘以的值(0.0 – 1.0,默许值为 1.0)
  • GPUImageSolidColorGenerator:这会输出具有纯色的生成图画。您需求运用 -forceProcessingAtSize 界说图画巨细:

    • color:用于填充图画的色彩,选用四重量格局。
  • GPUImageLuminanceThresholdFilter:亮度高于阈值的像素将显现为白色,低于阈值的像素将显现为黑色

    • threshold: 亮度阈值,从0.0到1.0,默许为0.5
  • GPUImageAdaptiveThresholdFilter:确认像素周围的局部亮度,假如低于该局部亮度则将像素变为黑色,假如高于该亮度则将像素变为白色。这关于在不同光照条件下挑选文本很有用。

    • blurRadiusInPixels:布景均匀含糊半径的乘数(以像素为单位),默许值为 4。
  • GPUImageAverageLuminanceThresholdFilter:这运用了阈值操作,其间阈值依据场景的均匀亮度不断调整。

    • thresholdMultiplier:这是一个因子,均匀亮度将乘以该因子以到达要运用的终究阈值。默许状况下,这是 1.0。
  • GPUImageHistogramFilter: This analyzes the incoming image and creates an output histogram with the frequency at which each color value occurs. The output of this filter is a 3-pixel-high, 256-pixel-wide image with the center (vertical) pixels containing pixels that correspond to the frequency at which various color values occurred. Each color value occupies one of the 256 width positions, from 0 on the left to 255 on the right. This histogram can be generated for individual color channels (kGPUImageHistogramRed, kGPUImageHistogramGreen, kGPUImageHistogramBlue), the luminance of the image (kGPUImageHistogramLuminance), or for all three color channels at once (kGPUImageHistogramRGB).

    • downsamplingFactor:这不是对每个像素进行采样,而是指示对图画的哪一部分进行采样。默许状况下,这是 16,最小值为 1。这是防止直方图饱满所必需的,直方图在过载之前只能为每个色彩值记载 256 个像素。
  • GPUImageHistogramGenerator:这是一个特别的过滤器,因为它首要用于与 GPUImageHistogramFilter 一同运用。它生成由 GPUImageHistogramFilter 生成的色彩直方图的输出表明,但它能够从头用于显现其他类型的值。它接纳图画并检查中心(垂直)像素。然后它在输出纹路的独自五颜六色图表中制作 RGB 重量的数值。您或许需求为此过滤器强制调整巨细以使其输出可见。

  • GPUImageAverageColor:这会处理输入图画并经过均匀图画中每个像素的 RGBA 重量来确认场景的均匀色彩。缩减进程用于在 GPU 上逐渐对源图画进行下采样,然后在 CPU 上进行短暂的均匀核算。此过滤器的输出没有意义,但您需求将 colorAverageProcessingFinishedBlock 特点设置为一个块,该块接纳四个色彩重量和一个帧时刻并对它们履行某些操作。

  • GPUImageLuminosity:与 GPUImageAverageColor 相同,这会将图画降低到其均匀亮度。您需求设置 luminosityProcessingFinishedBlock 来处理这个过滤器的输出,它只返回一个亮度值和一个帧时刻。

  • GPUImageChromaKeyFilter:关于图画中的给定色彩,将 alpha 通道设置为 0。这相似于 GPUImageChromaKeyBlendFilter,仅仅不是混合第二张图画以取得匹配的色彩,它不会接纳第二张图画,仅仅将给定的色彩通明。

    • thresholdSensitivity:色彩匹配需求与要替换的方针色彩有多挨近(默许为 0.4) – smoothing:色彩匹配的滑润度(默许为 0.1)

7.2 图画处理

  • GPUImageTransformFilter:这对图画运用任意 2-D 或 3-D 转化

    • affineTransform:这需求一个 CGAffineTransform 来调整二维图画 – transform3D:这需求一个 CATransform3D 来操作 3-D 图画 – ignoreAspectRatio:默许状况下,改换图画的纵横比保持不变,但能够将其设置为 YES 以使改换与纵横比无关
  • GPUImageCropFilter:将图画裁剪到特定区域,然后仅将该区域传递到过滤器的下一个阶段

    • cropRegion:要从图画中裁剪的矩形区域,标准化为 0.0 – 1.0 之间的坐标。(0.0, 0.0) 方位在图画的左上角。
  • GPUImageLanczosResamplingFilter:这使您能够运用 Lanczos 重采样对图画进行上采样或下采样,然后产生比标准线性或三线性插值显着更好的质量。只需运用 -forceProcessingAtSize: 设置过滤器的方针输出分辨率,图画将依据新尺寸从头采样。

  • GPUImageSharpenFilter:锐化图画

    • 清晰度:要运用的清晰度调整(-4.0 – 4.0,默许值为 0.0)
  • GPUImageUnsharpMaskFilter:运用反锐化蒙版

    • blurRadiusInPixels:底层高斯含糊的含糊半径。默许值为 4.0。 – intensity: 锐化的强度,从 0.0 开端,默许为 1.0
  • GPUImageGaussianBlurFilter:硬件优化的可变半径高斯含糊

    • texelSpacingMultiplier:纹素之间间距的乘数,规模从 0.0 开端,默许值为 1.0。调整此项或许会稍微增加含糊强度,但会在成果中引进伪影。强烈主张先运用其他参数,然后再触摸这个参数。 – blurRadiusInPixels:用于含糊的半径(以像素为单位),默许值为 2.0。这会调整高斯分布函数中的 sigma 变量。 – 含糊半径作为图画宽度的分数: – blurRadiusAsFractionOfImageHeight:设置这些特点将答应含糊半径随图画巨细缩放 – blurPasses:次序含糊传入图画的次数。经过的次数越多,过滤器越慢。
  • GPUImageBoxBlurFilter:硬件优化的可变半径框含糊

    • texelSpacingMultiplier:纹素之间间距的乘数,规模从 0.0 开端,默许值为 1.0。调整此项或许会稍微增加含糊强度,但会在成果中引进伪影。强烈主张先运用其他参数,然后再触摸这个参数。 – blurRadiusInPixels:用于含糊的半径(以像素为单位),默许值为 2.0。这会调整高斯分布函数中的 sigma 变量。 – 含糊半径作为图画宽度的分数: – blurRadiusAsFractionOfImageHeight:设置这些特点将答应含糊半径随图画巨细缩放 – blurPasses:次序含糊传入图画的次数。经过的次数越多,过滤器越慢。
  • GPUImageSingleComponentGaussianBlurFilter:对 GPUImageGaussianBlurFilter 的修正,仅对赤色重量进行操作

    • texelSpacingMultiplier:纹素之间间距的乘数,规模从 0.0 开端,默许值为 1.0。调整此项或许会稍微增加含糊强度,但会在成果中引进伪影。强烈主张先运用其他参数,然后再触摸这个参数。 – blurRadiusInPixels:用于含糊的半径(以像素为单位),默许值为 2.0。这会调整高斯分布函数中的 sigma 变量。 – 含糊半径作为图画宽度的分数: – blurRadiusAsFractionOfImageHeight:设置这些特点将答应含糊半径随图画巨细缩放 – blurPasses:次序含糊传入图画的次数。经过的次数越多,过滤器越慢。
  • GPUImageGaussianSelectiveBlurFilter:将焦点保存在圆形区域内的高斯含糊

    • blurRadiusInPixels:用于含糊的半径(以像素为单位),默许值为 5.0。这会调整高斯分布函数中的 sigma 变量。 – excludeCircleRadius:从含糊中扫除的圆形区域的半径 – excludeCirclePoint:从含糊中扫除的圆形区域的中心 – excludeBlurSize: 含糊部分和清晰圆圈之间的区域巨细 – aspectRatio:图画的纵横比,用于调整对焦区域的圆度。默许状况下,这与图画纵横比匹配,但您能够掩盖该值。
  • GPUImageGaussianBlurPositionFilter: GPUImageGaussianSelectiveBlurFilter 的逆函数,仅在特定圆圈内运用含糊

    • blurSize:含糊巨细的乘数,规模从 0.0 到 up,默许值为 1.0 – blurCenter: 含糊中心,默许为 0.5, 0.5 – blurRadius: 含糊的半径,默许为 1.0
  • GPUImageiOSBlurFilter:尝试在控制中心等方位仿制 iOS 7 上运用的布景含糊。

    • blurRadiusInPixels:用于含糊的半径(以像素为单位),默许值为 12.0。这会调整高斯分布函数中的 sigma 变量。 – 饱满度:饱满度规模从 0.0(彻底去饱满)到 2.0(最大饱满度),0.8 为正常水平 – 下采样:下采样的程度,然后对输入图画进行上采样以最小化高斯含糊内的核算,默许值为 4.0。
  • GPUImageMedianFilter:在 3×3 区域上取三个色彩重量的中值

  • GPUImageBilateralFilter:双方含糊,它试图含糊相似的色彩值,一同保存锐利的边际

    • texelSpacingMultiplier: 纹素读取间距的倍数,规模从 0.0 到上,默许为 4.0 – distanceNormalizationFactor:中心色彩和样本色彩之间间隔的归一化因子,默许值为 8.0。
  • GPUImageTiltShiftFilter:模拟歪斜移位镜头作用

    • blurRadiusInPixels:底层含糊的半径,以像素为单位。默许状况下为 7.0。 – topFocusLevel: 对焦区域顶部在图画中的归一化方位,该值应低于 bottomFocusLevel,默许 0.4 – bottomFocusLevel: 对焦区域底部在图画中的归一化方位,该值应高于 topFocusLevel,默许 0.6 – focusFallOffRate:图画远离对焦区域变得含糊的速率,默许 0.2
  • GPUImage3x3ConvolutionFilter:对图画运转 3×3 卷积

    • convolutionKernel:卷积核是一个 3×3 值矩阵,运用于像素及其周围的 8 个像素。矩阵按行优先次序指定,左上角的像素为 one.one,右下角的像素为 three.three。假如矩阵中的值加起来不等于 1.0,图画或许会变亮或变暗。
  • GPUImageSobelEdgeDetectionFilter:索贝尔边际检测,边际以白色杰出显现

    • 纹素宽度: – texelHeight:这些参数影响检测到的边际的可见性 – edgeStrength:调整过滤器的动态规模。较高的值会导致更强的边际,但会使强度色彩空间饱满。默许值为 1.0。
  • GPUImagePrewittEdgeDetectionFilter: Prewitt 边际检测,边际以白色杰出显现

    • 纹素宽度: – texelHeight:这些参数影响检测到的边际的可见性 – edgeStrength:调整过滤器的动态规模。较高的值会导致更强的边际,但会使强度色彩空间饱满。默许值为 1.0。
  • GPUImageThresholdEdgeDetectionFilter:履行 Sobel 边际检测,但运用阈值而不是供给渐变强度值

    • 纹素宽度: – texelHeight:这些参数影响检测到的边际的可见性 – edgeStrength:调整过滤器的动态规模。较高的值会导致更强的边际,但会使强度色彩空间饱满。默许值为 1.0。 – threshold:任何高于此阈值的边际都将是黑色的,任何低于该阈值的边际都是白色的。规模从 0.0 到 1.0,默许值为 0.8
  • GPUImageCannyEdgeDetectionFilter:这运用完好的 Canny 进程来杰出显现一个像素宽的边际

    • 纹素宽度: – texelHeight:这些参数影响检测到的边际的可见性 – blurRadiusInPixels:高斯含糊的根底含糊半径。默许值为 2.0。 – blurTexelSpacingMultiplier:底层含糊纹素间距乘数。默许值为 1.0。 – upperThreshold:任何梯度起伏高于此阈值的边际都将经过并显现在终究成果中。默许值为 0.4。 – lowerThreshold:梯度幅值低于此阈值的任何边际都将失败并从终究成果中删去。默许值为 0.1。
  • GPUImageHarrisCornerDetectionFilter:在输入图画上运转 Harris 角点检测算法,并生成一个图画,其间这些角点为白色像素,其他一切像素为黑色。能够设置 cornersDetectedBlock,您将在该回调中取得一个角列表(在标准化的 0..1 X,Y 坐标中),用于您想要履行的任何其他操作。

    • blurRadiusInPixels:底层高斯含糊的半径。默许值为 2.0。 – sensitivity:一个内部份额因子,用于调整过滤器中生成的转角图的动态规模。默许值为 5.0。 – threshold:点被检测为角点的阈值。这或许会依据尺寸、照明条件和 iOS 设备相机类型而有很大差异,因而或许需求进行一些实验才干合适您的状况。默许值为 0.20。
  • GPUImageNobleCornerDetectionFilter:在 Harris 角检测器上运转 Noble 变体。它的行为与上述 Harris 检测器相同。

    • blurRadiusInPixels:底层高斯含糊的半径。默许值为 2.0。 – sensitivity:一个内部份额因子,用于调整过滤器中生成的转角图的动态规模。默许值为 5.0。 – threshold:点被检测为角点的阈值。这或许会依据尺寸、照明条件和 iOS 设备相机类型而有很大差异,因而或许需求进行一些实验才干合适您的状况。默许值为 0.2。
  • GPUImageShiTomasiCornerDetectionFilter:运转 Shi-Tomasi 特征检测器。它的行为与上述 Harris 检测器相同。

    • blurRadiusInPixels:底层高斯含糊的半径。默许值为 2.0。 – sensitivity:一个内部份额因子,用于调整过滤器中生成的转角图的动态规模。默许值为 1.5。 – threshold:点被检测为角点的阈值。这或许会依据尺寸、照明条件和 iOS 设备相机类型而有很大差异,因而或许需求进行一些实验才干合适您的状况。默许值为 0.2。
  • GPUImageNonMaximumSuppressionFilter:现在仅用作 Harris 角点检测过滤器的一部分,这将对每个像素周围的 1 像素框进行采样,并确认中心像素的赤色通道是否是该区域的最大值。假如是,它会留下来。假如不是,则将一切色彩重量设置为 0。

  • GPUImageXYDerivativeFilter:Harris 角点检测过滤器中的一个内部组件,核算该像素左右像素的平方差、该像素上下像素的平方差,以及这两个差的乘积。

  • GPUImageCrosshairGenerator:这会在图画上制作一系列十字准线,最常用于辨认机器视觉特征。它不像其他滤镜那样接纳标准图画,而是接纳其 -renderCrosshairsFromArray:count: 办法中的一系列点,该办法履行实践绘图。您将需求强制此过滤器以您需求的特定输出巨细出现。

    • crosshairWidth:要在屏幕上制作的十字准线的宽度(以像素为单位)。
  • GPUImageDilationFilter:这履行图画胀大操作,其间矩形邻域中赤色通道的最大强度用于该像素的强度。要采样的矩形区域的半径在初始化时指定,规模为 1-4 像素。这是为了与灰度图画一同运用,它扩展了亮堂的区域。

  • GPUImageRGBDilationFilter:这与 GPUImageDilationFilter 相同,仅仅它作用于一切色彩通道,而不仅仅是赤色通道。

  • GPUImageErosionFilter:这履行图画腐蚀操作,其间矩形邻域中赤色通道的最小强度用于该像素的强度。要采样的矩形区域的半径在初始化时指定,规模为 1-4 像素。这是为了与灰度图画一同运用,它扩展了黑暗区域。

  • GPUImageRGBErosionFilter:这与 GPUImageErosionFilter 相同,仅仅它作用于一切色彩通道,而不仅仅是赤色通道。

  • GPUImageOpeningFilter:这对图画的赤色通道履行腐蚀,然后是相同半径的胀大。半径在初始化时设置,规模为 1-4 像素。这会过滤掉较小的亮堂区域。

  • GPUImageRGBOpeningFilter:这与 GPUImageOpeningFilter 相同,除了它作用于一切色彩通道,而不仅仅是赤色通道。

  • GPUImageClosingFilter:这对图画的赤色通道履行胀大,然后是相同半径的腐蚀。半径在初始化时设置,规模为 1-4 像素。这会过滤掉较小的暗区。

  • GPUImageRGBClosingFilter:这与 GPUImageClosingFilter 相同,仅仅它作用于一切色彩通道,而不仅仅是赤色通道。

  • GPUImageLocalBinaryPatternFilter:这对周围 8 个像素的赤色通道与中心像素的赤色通道的强度进行比较,将比较成果编码为成为该像素强度的位串。最不重要的位是右上角的比较,逆时针旋转到最右边的比较完毕。

  • GPUImageLowPassFilter:这对传入的视频帧运用低通滤波器。这基本上是累积先前帧与当时帧的加权翻滚均匀值。这可用于视频降噪、增加运动含糊或用于创立高通滤波器。

    • filterStrength:这控制了曾经累积的帧与当时帧混合的程度。规模从 0.0 到 1.0,默许值为 0.5。
  • GPUImageHighPassFilter:这对传入的视频帧运用高通滤波器。这是低通滤波器的逆进程,显现当时帧与之前帧的加权翻滚均匀值之间的差异。这关于运动检测最有用。

    • filterStrength:这控制了先前累积帧混合的程度,然后从当时帧中减去。规模从 0.0 到 1.0,默许值为 0.5。
  • GPUImageMotionDetector:这是一个依据高通滤波器的运动检测器。您设置 motionDetectionBlock 并在每个传入帧上为您供给场景中任何检测到的运动的质心(在标准化的 X、Y 坐标中)以及场景的运动强度。

    • lowPassFilterStrength:它控制在幕后运用的低通滤波器的强度,以树立与传入帧进行比较的基线。规模从 0.0 到 1.0,默许值为 0.5。
  • GPUImageHoughTransformLineDetector:运用 Hough 改换到平行坐标空间来检测图画中的线。这种办法彻底依据 PC 线进程,该进程由布尔诺科技大学的 Graph@FIT 研究小组开发,并在他们的出版物中进行了描绘:M. Dubsk、J. Havel 和 A. Herout。运用平行坐标和 OpenGL 实时检测线。SCCG 2011 会议记载,布拉迪斯拉发,SK,p.7 (medusa.fit.vutbr.cz/public/data…) 和 M. Dubsk, J . 哈维尔和A.赫鲁特。PClines – 运用平行坐标的线检测。2011 年 IEEE 核算机视觉和形式辨认会议 (CVPR),p.1489- 1494 (medusa.fit.vutbr.cz/public/data…).

    • edgeThreshold:一个阈值,关于该阈值,点被检测为属于用于确认线的边际。默许值为 0.9。 – lineDetectionThreshold:检测到局部最大值属于平行坐标空间中的一条线的阈值。默许值为 0.20。 – linesDetectedBlock:此块在检测线时调用,通常在每个处理过的帧上调用。包含 m、b 对 (y=mx+b) 中的归一化斜率和截距的 AC 数组被传入,以及检测到的行数计数和视频帧的当时时刻戳。
  • GPUImageLineGenerator:生成能够掩盖场景的线条的辅助类。能够运用 -setLineColorRed:green:blue 调整这些线条的色彩:

    • lineWidth:线条的宽度,以像素为单位,默许为 1.0。
  • GPUImageMotionBlurFilter:对图画运用定向运动含糊

    • blurSize:含糊巨细的乘数,规模从 0.0 到 up,默许值为 1.0 – blurAngle:含糊的视点方向,以度为单位。默许为 0 度。
  • GPUImageZoomBlurFilter:对图画运用定向运动含糊

    • blurSize:含糊巨细的乘数,规模从 0.0 到 up,默许值为 1.0 – blurCenter:含糊的归一化中心。(0.5, 0.5) 默许

7.3 混合形式

  • GPUImageChromaKeyBlendFilter:有挑选地用第二张图画替换第一张图画中的色彩

    • thresholdSensitivity:色彩匹配需求与要替换的方针色彩有多挨近(默许为 0.4) – smoothing:色彩匹配的滑润度(默许为 0.1)
  • GPUImageDissolveBlendFilter:运用两个图画的溶解混合

    • mix:第二个图画掩盖第一个图画的程度(0.0 – 1.0,默许为 0.5)
  • GPUImageMultiplyBlendFilter:运用两个图画的乘法混合

  • GPUImageAddBlendFilter:运用两个图画的加法混合

  • GPUImageSubtractBlendFilter:运用两个图画的减法混合

  • GPUImageDivideBlendFilter:运用两个图画的切割混合

  • GPUImageOverlayBlendFilter:运用两个图画的叠加混合

  • GPUImageDarkenBlendFilter:经过取图画之间每个色彩重量的最小值来混合两个图画

  • GPUImageLightenBlendFilter:经过取图画之间每个色彩重量的最大值来混合两个图画

  • GPUImageColorBurnBlendFilter:运用两个图画的色彩加深混合

  • GPUImageColorDodgeBlendFilter:运用两个图画的色彩减淡混合

  • GPUImageScreenBlendFilter:运用两个图画的屏幕混合

  • GPUImageExclusionBlendFilter:运用两个图画的扫除混合

  • GPUImageDifferenceBlendFilter:运用两个图画的差异混合

  • GPUImageHardLightBlendFilter:运用两个图画的强光混合

  • GPUImageSoftLightBlendFilter:运用两个图画的柔光混合

  • GPUImageAlphaBlendFilter:依据第二个的 alpha 通道将第二个图画混合到第一个图画上

    • mix:第二个图画掩盖第一个图画的程度(0.0 – 1.0,默许值为 1.0)
  • GPUImageSourceOverBlendFilter:在两个图画的混合上运用源

  • GPUImageColorBurnBlendFilter:运用两个图画的色彩加深混合

  • GPUImageColorDodgeBlendFilter:运用两个图画的色彩减淡混合

  • GPUImageNormalBlendFilter:运用两个图画的正常混合

  • GPUImageColorBlendFilter:运用两个图画的色彩混合

  • GPUImageHueBlendFilter:运用两个图画的色彩混合

  • GPUImageSaturationBlendFilter:运用两个图画的饱满度混合

  • GPUImageLuminosityBlendFilter:运用两个图画的光度混合

  • GPUImageLinearBurnBlendFilter:运用两个图画的线性加深混合

  • GPUImagePoissonBlendFilter:运用两个图画的泊松混合

    • mix:混合规模从 0.0(仅图画 1)到 1.0(仅图画 2 渐变),1.0 为正常等级 – numIterations:传播梯度的次数。假如您想挨近收敛,能够将其调到 100 甚至 1000。是的,这会很慢。
  • GPUImageMaskFilter:运用另一个图画遮盖一个图画

7.4 视觉作用

  • GPUImagePixellateFilter:对图画或视频运用像素化作用

    • fractionalWidthOfAPixel:像素有多大,作为图画宽度和高度的分数(0.0 – 1.0,默许 0.05)
  • GPUImagePolarPixellateFilter:依据极坐标而不是笛卡尔坐标对图画或视频运用像素化作用

    • center: 运用像素化的中心,默许为 (0.5, 0.5) – pixelSize:分数像素巨细,分为宽度和高度重量。默许值为 (0.05, 0.05)
  • GPUImagePolkaDotFilter:将图画分解为规矩网格内的五颜六色点

    • fractionalWidthOfAPixel:点有多大,作为图画宽度和高度的一部分(0.0 – 1.0,默许 0.05) – dotScaling:每个网格空间被点占用的份额,从 0.0 到 1.0,默许值为 0.9。
  • GPUImageHalftoneFilter:对图画运用半色彩作用,如新闻印刷

    • fractionalWidthOfAPixel:半色彩点有多大,作为图画宽度和高度的分数(0.0 – 1.0,默许 0.05)
  • GPUImageCrosshatchFilter:这会将图画转化为黑白穿插影线图画

    • crossHatchSpacing:用作剖面线间距的图画的小数宽度。默许值为 0.03。 – lineWidth:穿插影线的相对宽度。默许值为 0.003。
  • GPUImageSketchFilter:将视频转化为草图。这仅仅色彩回转的 Sobel 边际检测滤波器

    • 纹素宽度: – texelHeight:这些参数影响检测到的边际的可见性 – edgeStrength:调整过滤器的动态规模。较高的值会导致更强的边际,但会使强度色彩空间饱满。默许值为 1.0。
  • GPUImageThresholdSketchFilter: 和素描滤镜相同,仅仅对边际进行阈值处理,而不是灰度化

    • 纹素宽度: – texelHeight:这些参数影响检测到的边际的可见性 – edgeStrength:调整过滤器的动态规模。较高的值会导致更强的边际,但会使强度色彩空间饱满。默许值为 1.0。 – threshold:任何高于此阈值的边际都将是黑色的,任何低于该阈值的边际都是白色的。规模从 0.0 到 1.0,默许值为 0.8
  • GPUImageToonFilter:这运用 Sobel 边际检测在方针周围放置黑色边框,然后它量化图画中存在的色彩以赋予图画相似卡通的质量。

    • 纹素宽度: – texelHeight:这些参数影响检测到的边际的可见性 – threshold:边际检测的活络度,值越小越活络。规模从 0.0 到 1.0,默许值为 0.2 – quantizationLevels:终究图画中要表明的色彩等级数。默许值为 10.0
  • GPUImageSmoothToonFilter:这运用与 GPUImageToonFilter 相似的进程,仅仅它在卡通作用之前运用高斯含糊来滑润噪声。

    • 纹素宽度: – texelHeight:这些参数影响检测到的边际的可见性 – blurRadiusInPixels:底层高斯含糊的半径。默许值为 2.0。 – threshold:边际检测的活络度,值越小越活络。规模从 0.0 到 1.0,默许值为 0.2 – quantizationLevels:终究图画中要表明的色彩等级数。默许值为 10.0
  • GPUImageEmbossFilter:对图画运用浮雕作用

    • intensity: 压花的强度,从 0.0 到 4.0,1.0 为正常水平
  • GPUImagePosterizeFilter:这会将色彩动态规模减少到指定的步数,然后使图画具有卡通般的简略暗影。

    • colorLevels:将图画空间缩小到的色彩等级数。规模从 1 到 256,默许值为 10。
  • GPUImageSwirlFilter:在图画上创立漩涡失真

    • radius:从中心开端运用歪曲的半径,默许值为 0.5 – center:图画的中心(在 0 – 1.0 的标准化坐标中)环绕其旋转,默许值为 (0.5, 0.5) – angle:运用于图画的歪曲量,默许值为 1.0
  • GPUImageBulgeDistortionFilter:在图画上创立凸起失真

    • radius:从中心开端运用歪曲的半径,默许值为 0.25 – center:图画的中心(在 0 – 1.0 的规范化坐标中)环绕其歪曲,默许值为 (0.5, 0.5) – scale:要运用的失真量,从 -1.0 到 1.0,默许值为 0.5
  • GPUImagePinchDistortionFilter:创立图画的收缩失真

    • radius:从中心开端运用歪曲的半径,默许值为 1.0 – center:图画的中心(在 0 – 1.0 的规范化坐标中)环绕其歪曲,默许值为 (0.5, 0.5) – scale:要运用的失真量,从 -2.0 到 2.0,默许值为 1.0
  • GPUImageStretchDistortionFilter:创立图画的拉伸失真

    • center:图画的中心(在 0 – 1.0 的规范化坐标中)环绕其歪曲,默许值为 (0.5, 0.5)
  • GPUImageSphereRefractionFilter:模拟经过玻璃球体的折射

    • center:运用歪曲的中心,默许值为 (0.5, 0.5) – radius:歪曲的半径,规模从0.0到1.0,默许为0.25 – refractiveIndex:球体的折射率,默许值为 0.71
  • GPUImageGlassSphereFilter: 与 GPUImageSphereRefractionFilter 相同,仅仅图画没有回转,玻璃边际有一点点磨砂

    • center:运用歪曲的中心,默许值为 (0.5, 0.5) – radius:歪曲的半径,规模从0.0到1.0,默许为0.25 – refractiveIndex:球体的折射率,默许值为 0.71
  • GPUImageVignetteFilter:履行渐晕作用,在边际淡出图画

    • vignetteCenter: tex 坐标 (CGPoint) 中小插图的中心,默许值为 0.5, 0.5 – vignetteColor:用于小插图的色彩(GPUVector3),默许为黑色 – vignetteStart:间隔晕影作用开端的中心的归一化间隔,默许值为 0.5 – vignetteEnd:与晕影作用完毕的中心的归一化间隔,默许值为 0.75
  • GPUImageKuwaharaFilter:Kuwahara 图画笼统,取自 Kyprianidis 等人的作品。阿尔。在 GPU Pro 系列中的出版物“GPU 上的各向异性 Kuwahara 过滤”中。这会生成相似油画的图画,但核算量极大,因而在 iPad 2 上烘托帧或许需求几秒钟。这或许最合适静态图画。

    • radius:在整数中,指定在运用过滤器时要测验的中心像素的像素数,默许值为 4。更高的值创立更笼统的图画,但以更长的处理时刻为代价。
  • GPUImageKuwaharaRadius3Filter:Kuwahara 过滤器的修正版别,经过优化以仅在三个像素的半径规模内工作

  • GPUImagePerlinNoiseFilter:生成充满 Perlin 噪声的图画

    • 色彩开端: – colorFinish:正在生成的噪声的色彩规模 – scale:生成的噪声的缩放份额
  • GPUImageCGAColorspaceFilter: 模拟 CGA 显现器的色彩空间

  • GPUImageMosaicFilter:此过滤器选用输入图块集,图块的亮度必须上升。它会检查输入图画,并依据输入图块的亮度用输入图块替换每个显现图块。这个主意是仿制在其他运用程序中看到的 ASCII 视频过滤器,但 tileset 能够是任何东西。

    • 输入图块巨细: – 瓷砖数: – 显现图块巨细: – 上色
  • GPUImageJFAVoronoiFilter:生成 Voronoi 映射,供后期运用。

    • sizeInPixels:单个元素的巨细
  • GPUImageVoronoiConsumerFilter:承受 Voronoi 地图,并运用它来过滤传入的图画。

    • sizeInPixels:单个元素的巨细

如上所述,您还能够运用相似 C 的 OpenGL 上色言语轻松编写自己的自界说滤镜。

8. 自界说滤镜

8.1 依据原有的滤镜进行多个滤镜组合

咱们创立一个 承继自 GPUImageFilterGroup的类,往内部提早设置好咱们想要组合的滤镜方针.调好参数即可

#import <GPUImage/GPUImageFilterGroup.h>
@interface HPBeautifulGPUBaseImageFilter : GPUImageFilterGroup
@end
#import "HPBeautifulGPUBaseImageFilter.h"
@implementation HPBeautifulGPUBaseImageFilter
- (instancetype)init
{
    self = [super init];
    if (self) {
        [self addFilter:<#(GPUImageOutput<GPUImageInput> *)#>]
        [self addFilter:<#(GPUImageOutput<GPUImageInput> *)#>]
        [self addFilter:<#(GPUImageOutput<GPUImageInput> *)#>]
        ...
    }
    return self;
}
@end

8.2 依据滤镜基类GPUImageFilter

依据滤镜基类GPUImageFilter,则是经过创立一个新的滤镜类承继自GPUImageFilter,从头编写上色器程序;

举例说明:

#import <GPUImage/GPUImageFilter.h>
NSString * const kHPGPUImageLightFilterShaderString = SHADER_STRING
(
 precision highp float;
 uniform sampler2D inputImageTexture;
 varying vec2 textureCoordinate;
 uniform float time;
 const vec2 TextureCoordsVarying = vec2(400.0, 400.0);
 const vec2 TexSize = vec2(400.0, 400.0);
 const vec2 mosaicSize = vec2(16.0, 16.0);
 void main (void) {
     vec2 intXY = vec2(TextureCoordsVarying.x*TexSize.x, TextureCoordsVarying.y*TexSize.y);
     vec2 XYMosaic = vec2(floor(intXY.x/mosaicSize.x)*mosaicSize.x,floor(intXY.y/mosaicSize.y)*mosaicSize.y) + 0.5*mosaicSize;
     vec2 delXY = XYMosaic - intXY;
     float delL = length(delXY);
     vec2 UVMosaic = vec2(XYMosaic.x/TexSize.x,XYMosaic.y/TexSize.y);
     vec4 _finalColor;
     if(delL< 0.5*mosaicSize.x)
        _finalColor = texture2D(Texture,UVMosaic);
     else
        _finalColor = texture2D(Texture,TextureCoordsVarying);
     gl_FragColor = _finalColor;
 }
 );
@interface NewImageFilter : GPUImageFilter
@end 
@implementation NewImageFilter 
- (instancetype)init {
    self = [super initWithFragmentShaderFromString:kHPGPUImageLightFilterShaderString];
    return self;
}
@end

这儿的kHPGPUImageLightFilterShaderString便是新写的上色器程序,是依据GLSL言语编写的。

因而,咱们要自界说滤镜,还要学GLSL言语(后边回忆OPenGL ES 的时分 会重点重视)

9. 示例代码

给静态图增加滤镜

    //1.获取图片
    _myImage = [UIImage imageNamed:@"my.jpeg"];
    //2.初始化饱满度滤镜
    _disFilter = [[GPUImageSaturationFilter alloc]init];
    //设置饱满度值
    _disFilter.saturation = 1.0;
    //设置要烘托的区域 --图片巨细
    [_disFilter forceProcessingAtSize:_myImage.size];
    //运用单个滤镜
    [_disFilter useNextFrameForImageCapture];
    //3.创立图片组件--输入数据(静态图片)
    GPUImagePicture *stillImageSoucer = [[GPUImagePicture alloc]initWithImage:_myImage];
    //为图片增加一个滤镜
    [stillImageSoucer addTarget:_disFilter];
    //处理数据(图片)
    [stillImageSoucer processImage];
    //4.处理完结,从FrameBuffer帧缓存区中获取图片--输出数据
    UIImage *newImage = [_disFilter imageFromCurrentFramebuffer];
    //更新图片
    _myImagView.image = newImage;

文章引荐

GPUImage的 实战,我引荐几篇文章:

GPUImage2 内置滤镜介绍引荐: