how to take a screen shot from a mapview - iphone

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();

Related

Not able to merge two images into one

I'm trying to merge two images in one, and save that image onto the camera roll. But it just show a blank image. Can anyone help?
My code:
-(void)SaveFinalImage{
UIGraphicsBeginImageContext(self.view.bounds.size);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage *savedImg = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
UIImageWriteToSavedPhotosAlbum(savedImg, nil, nil, nil);
}
I have used this in my app.
UIImage *bottomImage = [UIImage imageNamed:#"bottom.png"]; //background image
UIImage *image = [UIImage imageNamed:#"top.png"]; //foreground image
CGSize newSize = CGSizeMake(width, height);
UIGraphicsBeginImageContext( newSize );
// Use existing opacity as is
[bottomImage drawInRect:CGRectMake(0,0,newSize.width,newSize.height)];
// Apply supplied opacity if applicable
[image drawInRect:CGRectMake(0,0,newSize.width,newSize.height) blendMode:kCGBlendModeNormal alpha:0.8];
UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
for more see my related answer on the same subject. iOS - Merging two images of different size

Crop Landscape Image Dynamically

I want to crop Image according to red View . There are some points to keep in mind.
1.Image can be scrolled and Zoomed.
2.Red ImageView is created Dynamically according to Image
UIImage* whole = [UIImage imageNamed:#"9.png"]; //I uses this image
CGImageRef cgImg = CGImageCreateWithImageInRect(whole.CGImage, CGRectMake(x, y, incX, incY));
UIImage* part = [UIImage imageWithCGImage:cgImg];
I just want to know How to find the Values of
x, y, incX, incY
Thanks...
Scenario 1: Normal (Not Scrolled)
Expected Result (Ignore Black Border On Top and Bottom)
Scenario 2:Scrolled
Expected Result (Ignore Black Border On Top and Bottom)
Scenario 3: Zoomed
And same Expected Result for the Zoomed One.
In all cases I want the respective Images Inside the Red Rectangle.
For all These I am Using this Code...
-(void)cropClicked:(UIButton*)sender
{
float zoomScale = 1.0 / [mainScrollView zoomScale];
CGRect rect;
rect.size.width = [redImageView bounds].size.width * zoomScale ;
rect.size.height = [redImageView bounds].size.height * zoomScale ;
rect.origin.x = ([mainScrollView bounds].origin.x + redImageView.frame.origin.x );
rect.origin.y = ([mainScrollView bounds].origin.y + redImageView.frame.origin.y );
CGImageRef cr = CGImageCreateWithImageInRect([[mainImageView image] CGImage], rect);
UIImage *cropped = [UIImage imageWithCGImage:cr];
mainImageView.image=cropped;
UIImageWriteToSavedPhotosAlbum(cropped, nil, nil, nil);
CGImageRelease(cr);
}
Well, as #HDdeveloper rightly said, you can use CGImageCreateWithImageInRect. This take 2 params, the first is the whole image, the second is the frame that you want to crop (so probably the frame of your red imageView).
The problem is that if you're targeting for both retina/non retina; if your whole image is an image #2x and you want to crop the image with the red imageview frame you have to double your frame to get the right screenshot.
So you can try with this method:
//Define the screen type:
#define isRetinaDisplay [[UIScreen mainScreen] respondsToSelector:#selector(displayLinkWithTarget:selector:)] && ([UIScreen mainScreen].scale == 2.0)
- (UIImage*)cropInnerImage:(CGRect)rect {
//Take a screenshot of the whole image
UIGraphicsBeginImageContextWithOptions(self.view.frame.size, NO, 0.0);
[self.view.layer renderInContext:UIGraphicsGetCurrentContext()];
UIImage* ret = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
CGRect rct;
//Double the frame if you're in retina display
if (isRetinaDisplay) {
rct=CGRectMake(rect.frame.origin.x*2, rect.frame.origin.y*2, rect.size.width*2, rect.size.height*2);
} else {
rct=rect;
}
//Crop the image from the screenshot
CGImageRef imageRef = CGImageCreateWithImageInRect([ret CGImage], rct);
UIImage *result = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);
//Save and open the result images with Preview.app
[UIImagePNGRepresentation(result) writeToFile: #"/tmp/testCrop.png" atomically: YES];
system("open /tmp/testCrop.png");
[UIImagePNGRepresentation(ret) writeToFile: #"/tmp/testRet.png" atomically: YES];
system("open /tmp/testRet.png");
//
return result;
}
Where the rect parameter must be your red image frame, and self.view.frame must be the equal to the wholeImageView.frame. You can skip the last 4 lines, these are just to see in your Mac what you're cropping.
PS: i use this method to crop an image and set it as background of UIView, this is the reason i have to double the frame.
You can use CGImageRef
pass your rect in the whole image. Then call this on button click
UIImage* whole = [UIImage imageNamed:#"9.png"]; //I uses this image
CGImageRef cgImg = CGImageCreateWithImageInRect(whole.CGImage, CGRectMake(x, y, incX, incY));
UIImage* part = [UIImage imageWithCGImage:cgImg];

Capturing CGRect does not give proper image. What to do?

I am capturing CGRect with following code. But the resulting image is not the image what i want. Image has some transparent background. What to do for removing transparent background as suggesting the picture.
- (UIImage *)captureScreenInRect:(CGRect)captureFrame {
CALayer *layer;
layer = imageScrollview.layer;
UIGraphicsBeginImageContext(imageScrollview.bounds.size);
CGContextClipToRect (UIGraphicsGetCurrentContext(),captureFrame);
\[layer renderInContext:UIGraphicsGetCurrentContext()\];
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return screenImage;
}
Translate your context so that its origin matches your captureFrame:
UIGraphicsBeginImageContext(imageScrollview.bounds.size);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(c, -captureFrame.origin.x, -captureFrame.origin.y);
[imageScrollView.layer renderInContext:c];
UIImage *screenImage = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
(written from memory, untested)
Additionally clipping the context is not necessary as the image is already clipped by the image context's bounds.
Try this one
CGRect cropRect = CGRectMake(imageScrollview.frame.origin.x+15, imageScrollview.frame.origin.y+15, WIDTH, HEIGHT);

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();

UIGraphicsBeginImageContext with parameters

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)