简体   繁体   中英

Core Graphics - how to crop non-transparent pixels out of a UIImage?

I have a UIImage that is reading from a transparent PNG (500px by 500px). Somewhere in the image, there is a picture that I want to crop out and save as a separate UIImage. I also want to store the X and Y coordinates based on how many transparent pixels there were on the left and top of the newly cropped rectangle.

I was able to crop an image with this code:

- (UIImage *)cropImage:(UIImage *)image atRect:(CGRect)rect
{
    double scale = image.scale;
    CGRect scaledRect = CGRectMake(rect.origin.x*scale,rect.origin.y*scale,rect.size.width*scale,rect.size.height*scale);

    CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], scaledRect);
    UIImage *cropped = [UIImage imageWithCGImage:imageRef scale:scale orientation:image.imageOrientation];
    CGImageRelease(imageRef);
    return cropped;
}

Which actually cuts off the transparent pixels on the top and left :S (this would be great if I was able to crop the pixels on right and bottom too!). It then resizes the rest of the image to the rectangle I specified. Unfortunately though I need to cut a picture that is in the middle of the image and I need the size to be able to be dynamic.

Been struggling with this for several hours now. Any ideas?

To crop an image, draw it into a smaller graphics context.

For example, let's say you have a 600x600 image. And let's say that you want to crop 200 pixels off all four sides. That leaves a 200x200 rectangle.

So you would make a 200x200 graphics context, using UIGraphicsBeginImageContextWithOptions . Then you would draw the image into it using drawAtPoint: , drawing at the point (-200,-200) . If you think about it, you will see that that offset causes just the 200x200 from the middle of the original to be drawn into the actual bounds of the context. Thus you have cropped the image by 200 pixels on all four sides, which is what we wanted to do.

Thus here is a generalized version, assuming that we know the amount to crop from the left, right, top, and bottom:

UIImage* original = [UIImage imageNamed:@"original.png"];
CGSize sz = [original size];
CGFloat cropLeft = ...;
CGFloat cropRight = ...;
CGFloat cropTop = ...;
CGFloat cropBottom = ...;
UIGraphicsBeginImageContextWithOptions(
    CGSizeMake(sz.width - cropLeft - cropRight, sz.height - cropTop - cropBottom), 
    NO, 0);
[original drawAtPoint:CGPointMake(-cropLeft, -cropTop)];
UIImage* cropped = UIGraphicsGetImageFromCurrentImageContext();
UIGraphicsEndImageContext();

After that, cropped is your cropped image.

The technical post webpages of this site follow the CC BY-SA 4.0 protocol. If you need to reprint, please indicate the site URL or the original address.Any question please contact:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM