UIGraphicsBeginImageContext with parameters - iphone

I am taking a screenshot in my application. I am able to take the screenshot.
Now I want to take the screenshot by specifying the x and y coordinate. Is that possible?
UIGraphicsBeginImageContext( self.view.bounds.size );
[self.view.layer renderInContext:UIGraphicsGetCurrentContext( )];
UIImage* aImage = UIGraphicsGetImageFromCurrentImageContext( );

UIGraphicsBeginImageContext(self.view.bounds.size);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(c, 0, -40); // <-- shift everything up by 40px when drawing.
[self.view.layer renderInContext:c];
UIImage* viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

If you're using a newer retina display device, your code should factor in the resolution by using UIGraphicsBeginImageContextWithOptions instead of UIGraphicsBeginImageContext:
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size,YES,2.0);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(c, 0, -40); // <-- shift everything up by 40px when drawing.
[self.view.layer renderInContext:c];
UIImage* viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
This will render the retina display image context.

Just do something like this, way easier than all those complex calculations
+ (UIImage *)imageWithView:(UIView *)view {
UIGraphicsBeginImageContextWithOptions([view bounds].size, NO, [[UIScreen mainScreen] scale]);
[[view layer] renderInContext:UIGraphicsGetCurrentContext()];
UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return result;
}

Here is Swift version
//Capture Screen
func capture()->UIImage {
UIGraphicsBeginImageContextWithOptions(self.view.bounds.size, false, UIScreen.mainScreen().scale)
self.view.layer.renderInContext(UIGraphicsGetCurrentContext()!)
let image = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
return image
}

swift version
UIGraphicsBeginImageContext(self.view.bounds.size)
let image: CGContextRef = UIGraphicsGetCurrentContext()!
CGContextTranslateCTM(image, 0, -40)
// <-- shift everything up by 40px when drawing.
self.view.layer.renderInContext(image)
let viewImage: UIImage = UIGraphicsGetImageFromCurrentImageContext()
UIGraphicsEndImageContext()
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil)

Related

Resolution of capture screen image is not retina

I am using the following code for capture a view on the screen but it is not as sharp as on the screen. the imageView size is 200x200point but the scale is 2.0 (with retina screen). The saved img size is 200x200 px. how could i make the img as sharp as the original one? Any help will be appreciated!
- (UIImage*)captureView:(UIView *)theView {
CGRect rect = theView.frame;
UIGraphicsBeginImageContext(rect.size);
CGContextRef context = UIGraphicsGetCurrentContext();
[theView.layer renderInContext:context];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
Try like that:
CGRect screenRect = [[UIScreen mainScreen] bounds];
UIGraphicsBeginImageContextWithOptions(screenRect.size, NO, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
You are using the old way of creating the image context. Use this instead:
UIGraphicsBeginImageContextWithOptions(rect.size, YES, [UIScreen mainScreen].scale);
The older UIGraphicsBeginImageContext function always assumes a scale of 1.0.
Replace 'YES' with 'NO' if you need the alpha channel.

UIImage screenshot loses its quality

I am merging two images and then I take a screenshot by applying this code:
UIGraphicsBeginImageContext(size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
img_AddText=viewImage;
[dragView removeFromSuperview];
imgV_SelectedImg.image=nil;
imgV_SelectedImg.image=img_AddText;
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
The problem is that when the final image loses its quality it blurs.
Try using the withOptions version of UIGraphicsBeginImageContext
UIGraphicsBeginImageContextWithOptions(size, NO, 0.0);
i got the snapshot with good quality and particular location of screen. By this code.
-(UIImage *)takeScreenShot
{
CGRect grabRect;
grabRect = CGRectMake(0,70,320,260);
UIGraphicsBeginImageContextWithOptions(grabRect.size, self.view.opaque, 0.0);
CGContextRef ctx = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(ctx, -grabRect.origin.x, -grabRect.origin.y);
[self.view.layer renderInContext:ctx];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return viewImage;
}
it gives me excellent snapshot..
I've made a category on UIImage class that may help you. It goes like this:
+ (UIImage*)imageWithView:(UIView *)view opaque:(BOOL)opaque bgColor:(UIColor*)bgColor{
UIGraphicsBeginImageContextWithOptions(view.bounds.size, opaque, [[UIScreen mainScreen] scale]);
if(!opaque){
[bgColor set];
}
[view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * img = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return img;
}
It works fine for me. No bluring was detected. Try to use it. If you'll still have it then most likely the problem is in your saving code...
Cheers... :)
UIGraphicsBeginImageContextWithOptions(size, NO, 2.0);
this solve my prblem by increasing scale from 1.0 to 2.0
Did you provide an image for retina display? You should check it. You might be running in a simulator (in retina).

UIGraphicsBeginImageContextWithOptions and UIImageJPEGRepresentation not working well together

So i have this code to create a UIImage:
UIGraphicsBeginImageContextWithOptions(border.frame.size, YES, 0);
[border.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *thumbnailImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
At this point, the size on the image is correct, 80x100.
Then it runs this code:
NSData *fullImageData = UIImageJPEGRepresentation(image, 1.0f);
And the NSData of the image returns an image at the size 160x200 - twice as much as it should be.
It's became clear the reason for this is the line:
UIGraphicsBeginImageContextWithOptions(border.frame.size, YES, 0);
The 0 on the end is the scale, and because it's 0 it goes by the devices scale factor. I keep it this way to maintain a clear image. However, when i set the image to 1, despite the image staying the size it should, it doesn't come out in retina quality. What i want to do is keep it in retina quality, but also keep it at the right size. Is there a way to do this?
Try resizing the UIImage before calling UIImageJPEGRepresentation
- (UIImage *)resizeImage:(UIImage*)image newSize:(CGSize)newSize {
CGRect newRect = CGRectIntegral(CGRectMake(0, 0, newSize.width, newSize.height));
CGImageRef imageRef = image.CGImage;
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0);
CGContextRef context = UIGraphicsGetCurrentContext();
// Set the quality level to use when rescaling
CGContextSetInterpolationQuality(context, kCGInterpolationHigh);
CGAffineTransform flipVertical = CGAffineTransformMake(1, 0, 0, -1, 0, newSize.height);
CGContextConcatCTM(context, flipVertical);
// Draw into the context; this scales the image
CGContextDrawImage(context, newRect, imageRef);
// Get the resized image from the context and a UIImage
CGImageRef newImageRef = CGBitmapContextCreateImage(context);
UIImage *newImage = [UIImage imageWithCGImage:newImageRef];
CGImageRelease(newImageRef);
UIGraphicsEndImageContext();
return newImage;
}
if([UIScreen mainScreen].scale > 1)
{
thumbnailImage = [self thumbnailImage newSize:CGSizeMake(thumbnailImage.size.width/[UIScreen mainScreen].scale, thumbnailImage.size.height/[UIScreen mainScreen].scale)];
}
- (UIImage *)imageWithImage{
UIGraphicsBeginImageContextWithOptions(newSize, NO, 0.0);
[image drawInRect:CGRectMake(0, 0, newSize.width, newSize.height)];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return newImage;
}

how to take a screen shot from a mapview

In my application i have used mapview. On particular place i can put annotation. i want to take the snap shot of that place with annotation in it.
i tried to implement this.
CGSize size = self.view.bounds.size;
CGRect screensize = CGRectMake(40,40,size.width-240,size.height-400);
UIGraphicsBeginImageContext(screensize.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *screenshotImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(screenshotImage, nil, nil, nil);
UIGraphicsEndImageContext();
this code takes the snap but it takes the snap from (0,0) coordinates. i want to take the snap from (40,40) coordinates and the size of the image should be 80*80.
How can i do this?
I don't think you can do it directly. Get the entire image and the crop the desired region.
CGSize size = self.view.bounds.size;
CGRect cropRect = CGRectMake(40, 40, 80, 80);
/* Get the entire on screen map as Image */
UIGraphicsBeginImageContext(size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage * mapImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
/* Crop the desired region */
CGImageRef imageRef = CGImageCreateWithImageInRect(mapImage.CGImage, cropRect);
UIImage * cropImage = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
/* Save the cropped image */
UIImageWriteToSavedPhotosAlbum(cropImage, nil, nil, nil);
UIGraphicsEndImageContext();

Capturing of Screen shot starting from 0,0

I am using following code to make a screen shot
UIGraphicsBeginImageContext(self.view.frame.size);
blendMode:kCGBlendModeClear alpha:1.0];
[self.view.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(viewImage, nil, nil, nil);
return viewImage;
It is working fine but it returns the full screen, and I want a screen shot of a particular Frame, like ( 100,100,200,200), I tried to make changes in:
UIGraphicsBeginImageContext(self.view.frame.size);
But no success.
Try this:
float x = 100;
float y = 100;
CGSize size = CGSizeMake(200,200);
UIGraphicsBeginImageContext(size);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(c, -x, -y);
[view.layer renderInContext:c];
UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
just use three line of code.
UIGraphicsBeginImageContext(CGSizeMake(320, 480));
[self.window.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *frame= UIGraphicsGetImageFromCurrentImageContext();