views:

618

answers:

4

I have a CALayer transformed in 3D on a offscreen UIView (much larger than 320x480).

How do I dump what is seen on this UIView to a UIImage?

NOTE: I Have edited the question to include this code...

This is how I create the layer...

CGRect area = CGRectMake (0,0,400,600];
vista3D = [[UIView alloc] initWithFrame:area ];

[self.view addSubview:vista3D];
[vista3D release];

transformed = [CALayer layer];
transformed.frame = area;
[vista3D.layer addSublayer:transformed];

CALayer *imageLayer = [CALayer layer];
imageLayer.doubleSided = YES; 

imageLayer.frame = area;
imageLayer.transform = CATransform3DMakeRotation(40 * M_PI / 180.0f, 1.0f, 0.0f, 0.0f);

imageLayer.contents = (id)myRawImage.CGImage;

[transformed addSublayer:imageLayer];

// Add a perspective effect
CATransform3D initialTransform = transformed.sublayerTransform;
initialTransform.m34 = 1.0 / -500;
transformed.sublayerTransform = initialTransform;

// now the layer is in perspective
// my next step is to "flatten" the composition into a UIImage

UIImage *thisIsTheResult = some magic command

thanks for any help!

EDIT 1: I have tried jessecurry solution but it gives me a flat layer without any perspective.

EDIT 2: I discovered a partial solution for this that works, but this solution gives me an image the size of the screen and I was looking for obtaining a higher resolution version, rendering off screen.

+3  A: 

Try this:

UIGraphicsBeginImageContext( myView.bounds.size );
[myView.layer renderInContext: UIGraphicsGetCurrentContext()];
UIImage* viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
jessecurry
thanks but this gives me the layer without the transformation. It seems renderInContext extracts the raw image from the layer and renders it in the context. What I need is to extract what is been seen on the view... in other words: if the layer is seen in perspective, this perspective must be present on the UImage.
Digital Robot
can you wrap the view that will be seen in perspective in some parent view, then call renderInContext: on the parent view?
jessecurry
this is exactly what is written in the question... the CALayer is on a UIView. Making [myView.layer renderInContext...] gives me the same non transformed result
Digital Robot
I have edited the original question now to include the code I am using to create the layer...
Digital Robot
-renderInContext: simply draws the contents of the layer into the Quartz context, so it would not take into account any transformations applied to the layer. It also doesn't render certain types of layers, such as the content of CAEAGLLayers.
Brad Larson
the problem is that the layer is transformed in 3D. Is that possible to apply the layer's 3D transforms to a CGLayer or CGContext?
Digital Robot
are you telling me that it is not possible to grab the view as it is seen and store it on a UIImage????
Digital Robot
A: 

In addition to @jessecurry's suggestions, have you tried this?

UIGraphicsBeginImageContext( myView.bounds.size );
[[myView.layer presentationLayer] renderInContext: UIGraphicsGetCurrentContext()];
UIImage* viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

Basically applying the same idea but on the presentatioLayer. This is supposed to return the layer with the any animations and properties applied to it.

bstahlhood
Thanks. I have tested this now and the result was the same as previously. I cannot believe that there's no way to grab what is been shown on the screen. I will continue to search for a solution.
Digital Robot
+3  A: 

Within the confines of the iPhone SDK, there is no way to do this. You can grab the contents of the screen with UIGetScreenImage or use -[CALayer renderInContext:] to have a layer draw into a CGContext, but forcing the GPU to composite only a subset of layers into a buffer is something that can only be achieved using private APIs and methods.

rpetrich
Yes, the solution I mentioned I have achieved is using UIGetScreenImage as renderInContext does not works. The problem is that UIGetScreenImage grabs the image in 320x480... in other words, low resolution...
Digital Robot
A: 

If you want higher resolution then you'll need to scale up the CGContext

Corin