如何在iOS中裁剪图像

27

我有一个照片应用程序,在其中一个部分中可以添加贴纸。当你完成后,我想保存图像。这是我用来完成此操作的代码。

if(UIGraphicsBeginImageContextWithOptions != NULL)
{
    UIGraphicsBeginImageContextWithOptions(self.view.frame.size, YES, 2.5);
} else {
    UIGraphicsBeginImageContext(self.view.frame.size);
}
CGContextRef contextNew=UIGraphicsGetCurrentContext();

[self.view.layer renderInContext:contextNew];

UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

UIGraphicsEndImageContext();
现在保存的图像是完整屏幕的图像,这很好,但现在我需要裁剪图像,而我不知道怎么做。您可以在下面的链接中查看该图像:http://dl.dropbox.com/u/19130454/Photo%202012-04-09%201%2036%2018%20PM.png 我需要裁剪: 左右各91像素 底部220像素
如有帮助,将不胜感激。如果我没有清楚地解释,请告诉我,我会尽力再解释一遍。

1
这可能是一个不错的资源:开源库,快速将图像裁剪添加到iOS应用程序中 - Lucien
可能是 iOS 图像裁剪 API 的重复问题。 - nalexn
4个回答

35

可以试试这样做

CGRect clippedRect  = CGRectMake(self.view.frame.origin.x+91, self.view.frame.origin.y, self.view.frame.size.width-91*2, self.view.frame.size.height-220);
CGImageRef imageRef = CGImageCreateWithImageInRect([image CGImage], clippedRect);
UIImage *newImage   = [UIImage imageWithCGImage:imageRef];
CGImageRelease(imageRef);

3
这忽略了图像的方向,因为UIImage支持它,但CGImage不支持。 - Dustin

4
以下代码可能会对您有所帮助。 您应该先通过以下方法获得正确的cropFrame。
-(CGRect)cropRectForFrame:(CGRect)frame
{
    // NSAssert(self.contentMode == UIViewContentModeScaleAspectFit, @"content mode must be aspect fit");

    CGFloat widthScale = imageview.superview.bounds.size.width / imageview.image.size.width;
    CGFloat heightScale = imageview.superview.bounds.size.height / imageview.image.size.height;

    float x, y, w, h, offset;
    if (widthScale<heightScale) {
        offset = (imageview.superview.bounds.size.height - (imageview.image.size.height*widthScale))/2;
        x = frame.origin.x / widthScale;
        y = (frame.origin.y-offset) / widthScale;
        w = frame.size.width / widthScale;
        h = frame.size.height / widthScale;
    } else {
        offset = (imageview.superview.bounds.size.width - (imageview.image.size.width*heightScale))/2;
        x = (frame.origin.x-offset) / heightScale;
        y = frame.origin.y / heightScale;
        w = frame.size.width / heightScale;
        h = frame.size.height / heightScale;
    }
    return CGRectMake(x, y, w, h);
}

然后您需要调用此方法以获取裁剪后的图像。
- (UIImage *)imageByCropping:(UIImage *)image toRect:(CGRect)rect
{
    // you need to update scaling factor value if deice is not retina display
    UIGraphicsBeginImageContextWithOptions(rect.size,
                                           /* your view opaque */ NO,
                                           /* scaling factor */ 2.0);

    // stick to methods on UIImage so that orientation etc. are automatically
    // dealt with for us
    [image drawAtPoint:CGPointMake(-rect.origin.x, -rect.origin.y)];

    UIImage *result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();

    return result;
}

这是我寻找已经有一个星期的解决方案。它运行得非常好! - Vishnuvardhan
我们能否为UIViewContentModeScaleAspectFill内容模式获得相同的效果? - Vishnuvardhan

3
- (UIImage*)imageByCropping:(CGRect)rect
{
    //create a context to do our clipping in
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    //create a rect with the size we want to crop the image to
    //the X and Y here are zero so we start at the beginning of our
    //newly created context
    CGRect clippedRect = CGRectMake(0, 0, rect.size.width, rect.size.height);
    CGContextClipToRect( currentContext, clippedRect);

    //create a rect equivalent to the full size of the image
    //offset the rect by the X and Y we want to start the crop
    //from in order to cut off anything before them
    CGRect drawRect = CGRectMake(rect.origin.x * -1,
                                 rect.origin.y * -1,
                                 self.size.width,
                                 self.size.height);

    //draw the image to our clipped context using our offset rect
    // CGContextDrawImage(currentContext, drawRect, self.CGImage);
    [self drawInRect:drawRect]; // This will fix getting inverted image from context.

    //pull the image from our cropped context
    UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();

    //pop the context to get back to the default
    UIGraphicsEndImageContext();

    //Note: this is autoreleased
    return cropped;
}

1
self.CGImage是什么? - Dvole
1
使用这种方法,我的图像被正确地裁剪了,但它自动翻转了。你能帮我解决一下吗?谢谢。 - iHulk
请尝试移除 @user2534373 UIGraphicsEndImageContext(); 这行代码。 - Mohit
self.CGImage 的意思是 image.CGImage。 - Dustin
尝试添加以下内容以补偿垂直翻转: CGContextScaleCTM(currentContext, 1.0, -1.0); - Drakes

-1
请参考以下链接以裁剪图像。

https://github.com/myang-git/iOS-Image-Crop-View

** How to Use **

Very easy! It is created to be a drop-in component, so no static library, no extra dependencies. Just copy ImageCropView.h and ImageCropView.m to your project, and implement ImageCropViewControllerDelegate protocol.
Use it like UIImagePicker:
- (void)cropImage:(UIImage *)image{
    ImageCropViewController *controller = [[ImageCropViewController alloc] initWithImage:image];
    controller.delegate = self;
    [[self navigationController] pushViewController:controller animated:YES];
}
- (void)ImageCropViewController:(ImageCropViewController *)controller didFinishCroppingImage:(UIImage *)croppedImage{
   image = croppedImage;
   imageView.image = croppedImage;
   [[self navigationController] popViewControllerAnimated:YES];
}
- (void)ImageCropViewControllerDidCancel:(ImageCropViewController *)controller{
    imageView.image = image;
    [[self navigationController] popViewControllerAnimated:YES];
}

请从链接中添加一些内容。 - Robert
嗨,我是Ramani。请帮个忙.. 我的项目需要剪裁图像以符合面部形状等多种不同类型的形状,并且需要对Objective C进行裁剪视图移动和缩放。 - Ramani Hitesh

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接