将CATransform3D转换为CIVector用于CIPerspectiveTransform,替换UIGetScreenImage

4

是否可以将CATransform3D转换为一组CIVectors,以便使用CATransform3D转换UIImage

我相信现在终于可以通过遍历视图层次结构并渲染单个图像,然后将CATransform3D应用于创建的图像来替换UIGetScreenImage()UIView/CALayer的3D变换扁平化为图像的能力。

我开始使用GPUImage,它确实接受CATransform3Ds以应用于UIImage,但不幸的是没有成功。附上我使用的代码和生成的图像链接。

模拟器截图

生成的图像

- (UIImage*)iterateLayerHierarchy:(CALayer*)layer
{
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(layer.frame.size.width,
                                                      layer.frame.size.height),
                                           NO,
                                           0.0);


    for (CALayer *sublayer in layer.sublayers)
    {
        UIImage* subImage;

        if (sublayer.sublayers.count > 1) {
            subImage = [self iterateLayerHierarchy:sublayer];
        } else {
            subImage = [UIView getImageFromLayer:sublayer];
        }
        CGRect imageRect;
        if (isRetina()) {
            imageRect = CGRectMake(sublayer.position.x-subImage.size.width/4,
                                   sublayer.position.y-subImage.size.height/4,
                                   subImage.size.width,
                                   subImage.size.height);
        }else{
            imageRect = CGRectMake(sublayer.position.x-subImage.size.width/2,
                                   sublayer.position.y-subImage.size.height/2,
                                   subImage.size.width,
                                   subImage.size.height);
        }
        [subImage drawInRect:imageRect];
        //sublayer.hidden = YES;
    }

    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return img;
}


+ (UIImage*) getImageFromLayer:(CALayer *)layer
{
    UIGraphicsBeginImageContextWithOptions(CGSizeMake(layer.bounds.size.width,
                                                      layer.bounds.size.height),
                                           NO,
                                           0.0);

    [layer renderInContext:UIGraphicsGetCurrentContext()];

    UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    if (!CATransform3DEqualToTransform(layer.transform, CATransform3DIdentity))
    {
        GPUImageTransformFilter *transformFilter = [[GPUImageTransformFilter alloc] init];
        transformFilter.transform3D = layer.transform;
        img = [transformFilter imageByFilteringImage:img];
    }

    return img;
}

理论上,可以计算CIPerspectiveTransformCIVector,但你真的不想这样做。CIPerspectiveTransform有缺陷。不相信我?只需交换图像的底部和顶部坐标,就会失败。(你会得到某种正方形东西)。 - idz
我一直在尝试,显然CIPerspectiveTransform的CIVector只需要角点,带有X、Y值。我通过使用convertPoint:toLayer获得了这些值,但还不够准确。我不确定是它有bug,还是我做得不太对。 - Matt Foley
1个回答

0
虽然这并非直接回答问题的方法,但是自iOS 7以来,已经不再需要解决这个问题了。 "UIGetScreenImage()" 已被 "drawViewHierarchyInRect:" 替代,后者能够同时捕获OpenGL图层和基于UIKit的视图。

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接