So, I know how to take a screenshot with UIKit:
UIWindow *window = [[[UIApplication sharedApplication] delegate] window];
UIGraphicsBeginImageContext(window.bounds.size);
[window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(image, nil, nil, nil);
And I know how to take a screenshot with OpenGL
// Some preparation to read pixels into a buffer
glReadPixels(0,0,backingWidth, backingHeight, GL_RGBA, GL_UNSIGNED_BYTE, buffer);
// Some code to massage the raw pixel data into an image
My app mixes OpenGL and UIKit, so any screenshot taken with just one method doesn't look right.
What's the best way to either
a) Composit the two images together or
b) Take a screenshot that can capture both OpenGL and UIKit together
This is a similar post which has some answers. Apparently you can use either UIGetScreenImage, or glReadPixels to do this task. Hope that helps!
Related
Is there a way to grab the pixels from an UIWebView and render it to an opengl texture?
I don't know what it takes to load an opengl texture. But this will convert the data from a view into a jpeg.
UIGraphicsBeginImageContext(self.bounds.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
sorry for the half answer. hope someone can take it from here...
I've been using UIGetScreenImage() to get a screenshot of a UIImagePickerController. Basically I use the camera overlay and then when I take the screenshot, I have the image that the camera preview had been showing and my overlay on there too, which is exactly what I need.
Now UIGetScreenImage() has been banned, I've not been able to find a way to do this. It just shows black for the camera.
Edit: all of my other views are showing absolutely fine, just not the actual camera preview. Any ideas??!?!?
Here's the code I am using at the moment.
UIGraphicsBeginImageContext(picker.view.bounds.size);
[picker.view.layer renderInContext:UIGraphicsGetCurrentContext()];
CGContextDrawImage(context, bounds, camView.CGImage);
UIImage* screenImage = UIGraphicsGetImageFromCurrentImageContext();
UIImageWriteToSavedPhotosAlbum(screenImage, nil, nil, nil);
UIGraphicsEndImageContext();
Any ideas how I can get the overlay + the camera image?
Thanks!
This is slightly different than yours.
CGRect screenRect = [[UIScreen mainScreen] bounds];
UIGraphicsBeginImageContext(screenRect.size);
[self.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *sShot = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum (sShot, nil, nil, nil);
Does that work?
If not, you might want to try asking over at iphonedevsdk.com since they specialize in all things iPhone.
Have them take a picture. Then overlay your image on top of it.
Create a UIImage from two other UIImages on the iPhone
I'd like to get the image that is being displayed on the UIImagePickerController when user uses the camera. And when I get I want to process the image and display instead of regular camera view.
But the problem is when I want to get the camera view, the image is just a black rectangle.
Here's my code:
UIView *cameraView = [[[[[[imagePicker.view subviews] objectAtIndex:0]
subviews] objectAtIndex: 0]
subviews] objectAtIndex: 0];
UIGraphicsBeginImageContext( CGSizeMake(320, 427) );
[cameraView.layer renderInContext: UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
imageToDisplay.image = [PixelProcessing processImage: viewImage]; //In this case the image is black
//imageToDisplay.image = viewImage; //In this case the image is black too
//imageToDisplay.image = [UIImage imageNamed: #"icon.png"]; //In this case image is being displayed properly
What am I doing wrong?
Thanks.
This one is also working quite good. Use it when the camera preview is open:
UIImage *viewImage = [[(id)objc_getClass("PLCameraController")
performSelector:#selector(sharedInstance)]
performSelector:#selector(_createPreviewImage)];
But as far as I found out it brings the same results than the following solution which takes a 'screenshot' of the current screen:
extern CGImageRef UIGetScreenImage();
CGImageRef cgoriginal = UIGetScreenImage();
CGImageRef cgimg = CGImageCreateWithImageInRect(cgoriginal, rect);
UIImage *viewImage = [UIImage imageWithCGImage:cgimg];
CGImageRelease(cgoriginal);
CGImageRelease(cgimg);
A problem I didn't still find a fix for is, how can one get the camera image very fast without any overlays?
The unofficial call is:
UIGetScreenImage()
which you declare above the #implementation as:
extern CGImageRef UIGetScreenImage();
There may be a documented way to do this in 3.1, but I'm not sure. If not, please please file a Radar with Apple asking them to make some kind of screen grab access public!!!
That uses your same AppleID you log in to the iPhone development portal with.
Update: This call is not yet documented, but Apple explicitly has given the OK to use it with App Store apps.
at least for now, there's no way to do this. (certainly no official documented way, and as far as I know nobody's figured out an unofficial way either.)
the camera preview data is being drawn by the OS in some way that bypasses the normal graphics methods.
with fw 2.2 i was able to get a screenshot using the private method _createCGImageRefRepresentationInFrame of UIWindow. In 3.0 doesn't exist anymore.
I used that method with the PLCameraView over a window to take a small video just by get as much screenshot as possible. Now i tried with the CALayer of the PLPreviewView and -renderInContext: method, but it always render the view as it has the iris closed.
How can i take a screenshot of what the cameraView is showing?
Thanks
Marco
Try for following code snippet to get
CGImageRef imageRef = [[UIApplication sharedApplication] _createDefaultImageSnapshot];
UIImage* img = [UIImage imageWithCGImage:imageRef];
//Now you can save it the way you want
//May as following
//oops yes this image is just the screenshot so better take care of unwanted image side
//So cut crap out from the image captured
UIImageWriteToSavedPhotosAlbum(img, nil, nil, nil);
I am looking for a way to capture a screenshot on the iPhone with the top status bar included, I am currently using the following code:
UIGraphicsBeginImageContext(self.view.bounds.size); //self.view.window.frame.size
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
The above code sucessfully takes a screenshot of the iPhone UIView but does not include the top status bar (In its place is just a blank 20px space).
As of iOS 7, you can do this without the use of private APIs using
UIView *screenshotView = [[UIScreen mainScreen] snapshotViewAfterScreenUpdates:NO];
See my answer to this question:
Moving status bar in iOS 7
You can get the entire contents of the screen by calling the private API UIGetScreenImage. See my previous answer to a similar question for details.
As of Oct 8, 2009, the use of UIGetScreenImage got my app rejected! :( I would not advise using it. I believe Apple is trying to clean up all the apps and make them conform to the new 3.x OS/APIs. I'm looking for an alternative. If anyone has any suggestions. The video API?
Instead of using private API, why not render the entire UIWindow into the image context? It might be enough to replace self.view with self.view.window in your code.
You can also get the current window(s) as a property of the [UIApplication sharedApplication] instance. It's possible the status bar is on a separate window layer and maybe you'll have to render the windows in order.
Something like this:
UIGraphicsBeginImageContext(self.view.window.frame.size);
for (UIWindow *window in [[UIApplication sharedApplication] windows]) {
[window.layer renderInContext:UIGraphicsGetCurrentContext()];
}
UIImage *screenshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
At any rate, you probably don't need to resort to private API.