Like you can see in my code, I take a screenshot and save it to the photo album.
//for retina displays
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, NO, [UIScreen mainScreen].scale);
} else {
UIGraphicsBeginImageContext(self.view.bounds.size);
}
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
At the beginning I used webview.size
instead of self.view.bounds.size
and it was working properly because the view was located at 0/0
. But now I centered the WebView but the pictures is starts at 0/0
for the given size.
How can I configure that the screenshot starts at another location
(e.g. 300/150
) for the given size?
Or is there another way to take a picture of an UIWebView
?
You need to make two changes in order to only grab a portion of the screen:
- Create a smaller image - use the size of the rect you'd like to capture.
- Move the origin of the context that you're rendering into to be negative x/y of the rect you'd like to capture.
After that, you just render the layer into the context as you were doing, and you should get what you're looking for. Something like this ought to do it:
CGRect grabRect = CGRectMake(40,40,300,200);
//for retina displays
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(grabRect.size, NO, [UIScreen mainScreen].scale);
} else {
UIGraphicsBeginImageContext(grabRect.size);
}
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -grabRect.origin.x, -grabRect.origin.y);
[self.view.layer renderInContext:ctx];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
I've taken and tested @escrafford's answer above, and got it to work just fine. I did test it in the context of making it a category method on UIView, so that the 'grabRect' can be paramaterized. Here's that code, as a UIView category that returns you a UIImageView:
/**
Takes a screenshot of a UIView at a specific point and size, as denoted by
the provided croppingRect parameter. Returns a UIImageView of this cropped
region.
CREDIT: This is based on @escrafford's answer at http://stackoverflow.com/a/15304222/535054
*/
- (UIImageView *)rp_screenshotImageViewWithCroppingRect:(CGRect)croppingRect {
// For dealing with Retina displays as well as non-Retina, we need to check
// the scale factor, if it is available. Note that we use the size of teh cropping Rect
// passed in, and not the size of the view we are taking a screenshot of.
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)]) {
UIGraphicsBeginImageContextWithOptions(croppingRect.size, YES, [UIScreen mainScreen].scale);
} else {
UIGraphicsBeginImageContext(croppingRect.size);
}
// Create a graphics context and translate it the view we want to crop so
// that even in grabbing (0,0), that origin point now represents the actual
// cropping origin desired:
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -croppingRect.origin.x, -croppingRect.origin.y);
[self.layer renderInContext:ctx];
// Retrieve a UIImage from the current image context:
UIImage *snapshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
// Return the image in a UIImageView:
return [[UIImageView alloc] initWithImage:snapshotImage];
}
I solved my problem but didn't answer the question:
I created a subclass of UIView
and moved my UIWebView
in there, so that it is located 0/0 relative to the subclass. Then use the size of the WebView:
UIGraphicsBeginImageContext(webview.frame.size);
and the other code from above.
Now you can move the subclass to every location you want.
Note: If you have labels like date/time label you have to move them too or you won't see them on the picture.
So create a subclass of
UIView
and move everyIBOutlet
you want to be seen on the picture in there.
The question is still open: So is it possible to take a picture of a specific area of the screen?
Kind Regards. $h@rky
- (void)drawRect:(CGRect)rect {
UIGraphicsBeginImageContext(self.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
}
You could call this to your view :]
来源:https://stackoverflow.com/questions/8702834/programmatically-take-a-screenshot-of-specific-area