Hei, I went through the example for saving images and afterwards I wanted to save only a part of the screen. I managed to save the part starting at the upper left corner of the
a little modification to Travis' answer makes it independent from the image but dependent on the canvas origin:
-(C4Image *)cropImage:(C4Image *)originalImage withOrigin:(CGPoint)origin toArea:(CGRect)rect{
//grab the image scale
CGFloat scale = originalImage.UIImage.scale;
//begin an image context
UIGraphicsBeginImageContextWithOptions(rect.size, NO, scale);
//create a new context ref
CGContextRef c = UIGraphicsGetCurrentContext();
//shift BACKWARDS in both directions because this moves the image
//the area to crop shifts INTO: (0, 0, rect.size.width, rect.size.height)
CGContextTranslateCTM(c, origin.x-rect.origin.x, origin.y-rect.origin.y);
//render the original image into the context
[originalImage renderInContext:c];
//grab a UIImage from the context
UIImage *newUIImage = UIGraphicsGetImageFromCurrentImageContext();
//end the image context
UIGraphicsEndImageContext();
//create a new C4Image
C4Image *newImage = [C4Image imageWithUIImage:newUIImage];
//return the new image
return newImage;
}
This method what I wrote for this is works perfectly:
+ (UIImage*) getTheArea:(CGRect)area inView:(UIView*)view{
if ([[UIScreen mainScreen] respondsToSelector:@selector(scale)])
UIGraphicsBeginImageContextWithOptions(CGSizeMake(area.size.width, area.size.height), NO, [UIScreen mainScreen].scale);
else
UIGraphicsBeginImageContext(view.bounds.size);
CGContextRef c = UIGraphicsGetCurrentContext();
CGContextTranslateCTM(c, -area.origin.x, -area.origin.y); // <-- shift everything up by 40px when drawing.
[view.layer renderInContext:c];
UIImage* thePrintScreen = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();
return thePrintScreen;
}
for example, if you want to make a printscreen of your main view, in (100,50,100,100)
UIImage* image = [self getTheArea:CGRectMake(100,50,100,100) inView:view];
To do this with C4Image objects, you can modify incmiko's answer to look like the following:
#import "C4Workspace.h"
@implementation C4WorkSpace{
C4Image *image;
C4Image *croppedImage;
}
-(void)setup {
image=[C4Image imageNamed:@"C4Sky.png"];
image.origin=CGPointMake(0, 20);
croppedImage = [self cropImage:image toArea:CGRectMake(150,50,100,100)];
croppedImage.origin = CGPointMake(20, 360);
[self.canvas addObjects:@[image,croppedImage]];
}
-(C4Image *)cropImage:(C4Image *)originalImage toArea:(CGRect)rect{
//grab the image scale
CGFloat scale = originalImage.UIImage.scale;
//begin an image context
UIGraphicsBeginImageContextWithOptions(rect.size, NO, scale);
//create a new context ref
CGContextRef c = UIGraphicsGetCurrentContext();
//shift BACKWARDS in both directions because this moves the image
//the area to crop shifts INTO: (0, 0, rect.size.width, rect.size.height)
CGContextTranslateCTM(c, -rect.origin.x, -rect.origin.y);
//render the original image into the context
[originalImage renderInContext:c];
//grab a UIImage from the context
UIImage *newUIImage = UIGraphicsGetImageFromCurrentImageContext();
//end the image context
UIGraphicsEndImageContext();
//create a new C4Image
C4Image *newImage = [C4Image imageWithUIImage:newUIImage];
//return the new image
return newImage;
}
@end
Aside from the comments in the code there are a couple other things to be aware of:
The "area" you're cropping will always be in reference to the "image" that you're cropping. So, if you want to crop {150,50}
from the image, and the image's origin is at {20,20}
then it will LOOK like you are cropping {170,70}
from the CANVAS.
The C4Image
object actually has a renderInContext:
method, so you don't have to do this from the image's layer.
C4Image
objects wrap UIImage
objects, which is why we build a new one using the UIImage
that we get from the current context