iossavescreenshotc4

C4 saving part of an image


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 image but I actually want to save the center of my screen. The magic to save only a part of an image is setting up the Graphics Context with a certain size, like this:

 UIGraphicsBeginImageContextWithOptions(CGSizeMake(300, 300), YES, 5.0f);

I thought there might be a way to use a CGRect instead of the size, but that gives me an error. any other attempts or thoughts? Do I have to go through the pixels of my screenshot, grab those needed and make a new image out of that (that would be the kind of complicated way I can think of but maybe there is an easier one)?


Solution

  • 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:

    1. 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.

    2. The C4Image object actually has a renderInContext: method, so you don't have to do this from the image's layer.

    3. C4Image objects wrap UIImage objects, which is why we build a new one using the UIImage that we get from the current context