iosobjective-ccropcgcontextrefdownsize

cropping an area CGRect from UIGraphicsImageContext


I have a CGPath shaped like an arrow that I am drawing in the CGContext of my current view. I would like to generate a miniature version (thumbnail) of the arrow to add it as an Image to a UITableView showing all selected arrows.

I am succeeding to downscale a picture of the full context which leaves the arrow smaller than it should be. Ideally I would like to crop the image of the full context to the bounds of the arrow. However, I was not yet successful. Any leads? Thanks for the help!

Here are a picture of the full view containing an arrow and another picture of the thumbnail I am generating. enter image description here enter image description here

Ideally the thumbnail above would be cropped to contain the arrow only - not the full context.

The code I use is the follwoing:

- (UIImage*) imageForObject:(id<GraphicalObject>) object 
                     inRect:(CGRect)rect {

    UIImage *image = [UIImage new];
    CGRect objectBounds = [object objectBounds];
    UIGraphicsBeginImageContext(self.view.frame.size);//objectBounds.size);
    CGContextRef context =UIGraphicsGetCurrentContext();
    [object drawInContext:context];
    //doesn't work 
    CGContextClipToRect(context, objectBounds);

    image = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return image;
}

Solution

  • The CGRect called objectBounds has two components, an origin and a size. In order the draw the object correctly as a thumbnail, the code needs to scale the image (to get the size right) and translate the image (to move the origin to {0,0}). So the code looks like this

    - (UIImage *)getThumbnailOfSize:(CGSize)size forObject:(UIBezierPath *)object
    {
        // to maintain the aspect ratio, we need to compute the scale
        // factors for x and y, and then use the smaller of the two
        CGFloat xscale = size.width / object.bounds.size.width;
        CGFloat yscale = size.height / object.bounds.size.height;
        CGFloat scale = (xscale < yscale) ? xscale : yscale;
    
        // start a graphics context with the thumbnail size
        UIGraphicsBeginImageContext( size );
        CGContextRef context = UIGraphicsGetCurrentContext();
    
        // here's where we scale and translate to make the image fit
        CGContextScaleCTM( context, scale, scale );
        CGContextTranslateCTM( context, -object.bounds.origin.x, -object.bounds.origin.y );
    
        // draw the object and get the resulting image
        [object stroke];
        UIImage *image = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
    
        return image;
    }