GPUImage源码解读(九)

GPUImageUIElement

与GPUImagePicture类似可以作为响应链源。与GPUImagePicture不同的是,它的数据不是来自图片,而是来自于UIView或CALayer的渲染结果,类似于对UIView或CALayer截图。GPUImageUIElement继承自GPUImageOutput,从而可以知道它能够作为输出,由于它没有实现GPUImageInput协议,不能处理输入

  • 初始化方法

- (id)initWithView:(UIView *)inputView;
- (id)initWithLayer:(CALayer *)inputLayer;

通过UIView或CALayer进行初始化,初始化的过程中调用 [layer renderInContext:imageContext] 进行渲染,渲染后便生成纹理对象。

// 带时间的更新方法
- (void)updateWithTimestamp:(CMTime)frameTime;
{
    [GPUImageContext useImageProcessingContext];

    //相素大小
    CGSize layerPixelSize = [self layerSizeInPixels];

    //创建数据内存空间
    GLubyte *imageData = (GLubyte *) calloc(1, (int)layerPixelSize.width * (int)layerPixelSize.height * 4);

    //使用RGB模式的颜色空间
    CGColorSpaceRef genericRGBColorspace = CGColorSpaceCreateDeviceRGB();

    //位图
    CGContextRef imageContext = CGBitmapContextCreate(imageData, (int)layerPixelSize.width, (int)layerPixelSize.height, 8, (int)layerPixelSize.width * 4, genericRGBColorspace,  kCGBitmapByteOrder32Little | kCGImageAlphaPremultipliedFirst);
//    CGContextRotateCTM(imageContext, M_PI_2);
    // 矩形Y轴正方向平移layerPixelSize.height
    CGContextTranslateCTM(imageContext, 0.0f, layerPixelSize.height);
    CGContextScaleCTM(imageContext, layer.contentsScale, -layer.contentsScale);
    //        CGContextSetBlendMode(imageContext, kCGBlendModeCopy); // From Technical Q&A QA1708: http://developer.apple.com/library/ios/#qa/qa1708/_index.html

    [layer renderInContext:imageContext];

    CGContextRelease(imageContext);
    CGColorSpaceRelease(genericRGBColorspace);

    // TODO: This may not work
    outputFramebuffer = [[GPUImageContext sharedFramebufferCache] fetchFramebufferForSize:layerPixelSize textureOptions:self.outputTextureOptions onlyTexture:YES];

    glBindTexture(GL_TEXTURE_2D, [outputFramebuffer texture]);
    // no need to use self.outputTextureOptions here, we always need these texture options
    glTexImage2D(GL_TEXTURE_2D, 0, GL_RGBA, (int)layerPixelSize.width, (int)layerPixelSize.height, 0, GL_BGRA, GL_UNSIGNED_BYTE, imageData);

    //析构数据
    free(imageData);

    for (id<GPUImageInput> currentTarget in targets)
    {
        if (currentTarget != self.targetToIgnoreForUpdates)
        {
            NSInteger indexOfObject = [targets indexOfObject:currentTarget];
            NSInteger textureIndexOfTarget = [[targetTextureIndices objectAtIndex:indexOfObject] integerValue];

            [currentTarget setInputSize:layerPixelSize atIndex:textureIndexOfTarget];
            [currentTarget newFrameReadyAtTime:frameTime atIndex:textureIndexOfTarget];
        }
    }    
}
  • 其它方法

- (CGSize)layerSizeInPixels;
- (void)update;
- (void)updateUsingCurrentTime;
// 获取像素大小
- (CGSize)layerSizeInPixels;
{
    CGSize pointSize = layer.bounds.size;
    return CGSizeMake(layer.contentsScale * pointSize.width, layer.contentsScale * pointSize.height);
}

// 更新方法
- (void)update;
{
    [self updateWithTimestamp:kCMTimeIndefinite];
}

Last updated