Is it possible to convert a CATransform3D
into a set of CIVectors
in order to transform a UIImage
with a CATransform3D
?
I believe that is now finally possible to replace UIGetScreenImage()
's ability to flatten 3D transforms of UIView/CALayer
into an image by traversing the view hierarchy and rendering individual images, and then applying the CATransform3D
to the image that was created.
I started working with GPUImage
, which does accept CATransform3Ds
to apply to a UIImage
and unfortunately had no luck. Attached is the code I was using, and links to the images that were produced.
- (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;
}
While not a direct answer to the question, as of iOS 7 there is no longer a need to solve this problem. "UIGetScreenImage()" has effectively been replaced by "drawViewHierarchyInRect:", which is able to capture both OpenGL layers and UIKit based views simultaneously.