将图像裁剪为叠加的形状 - iOS

时间:2014-09-09 22:42:01

标签: ios uiimagepickercontroller uibezierpath

我正在使用pickerController的视图和uinavigationcontrollerdelegate添加叠加层,如下所示。

-(void)navigationController:(UINavigationController *)navigationController didShowViewController:  (UIViewController *)viewController animated:(BOOL)animated{
    if ([navigationController.viewControllers count] == 3)
     {
       CGFloat screenHeight = [[UIScreen mainScreen] bounds].size.height;

       UIView *plCropOverlay = [[[viewController.view.subviews objectAtIndex:1]subviews] objectAtIndex:0];

       plCropOverlay.hidden = YES;

       int position = 0;

       if (screenHeight == 568)
       {
           position = 124;
       }
       else
       {
          position = 80;
      }

      CAShapeLayer *circleLayer = [CAShapeLayer layer];

      UIBezierPath *path2 = [UIBezierPath bezierPathWithOvalInRect:
                           CGRectMake(0.0f, position, 320.0f, 320.0f)];
      [path2 setUsesEvenOddFillRule:YES];

      [circleLayer setPath:[path2 CGPath]];

      [circleLayer setFillColor:[[UIColor clearColor] CGColor]];
      UIBezierPath *path = [UIBezierPath bezierPathWithRoundedRect:CGRectMake(0, 0, 320, screenHeight-72) cornerRadius:0];

      [path appendPath:path2];
      [path setUsesEvenOddFillRule:YES];

      CAShapeLayer *fillLayer = [CAShapeLayer layer];
      fillLayer.path = path.CGPath;
      fillLayer.fillRule = kCAFillRuleEvenOdd;
      fillLayer.fillColor = [UIColor blackColor].CGColor;
      fillLayer.opacity = 0.8;
      [viewController.view.layer addSublayer:fillLayer];

  }
}

当添加上面定义的叠加层时,我倾向于获得此视图:

enter image description here

我可以使用定义的CGRect将图像精确地裁剪为正方形。

   CGImageRef imageRef = CGImageCreateWithImageInRect([imageToCrop CGImage], rect);

   UIImage *cropped = [UIImage imageWithCGImage:imageRef];
   CGImageRelease(imageRef);

如果有圆形叠加层并且imagePickers编辑属性为YES,那么如何处理此问题?我可以放大并缩小图片。我如何在这里使用BezierPath?

3 个答案:

答案 0 :(得分:7)

你的问题addClip的简短回答,但你提到你是初学者,所以这里是从A到Z的所有步骤!!

首先,尝试此类别,看看它是否有帮助。 (如果您不熟悉w /类别有谷歌或只是在评论中询问。)

-(UIImage *)doMask
    {
    UIImage *maskImage = [UIImage imageNamed:@"yourMask.png"];

    CGImageRef maskRef = maskImage.CGImage;

    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
        CGImageGetHeight(maskRef),
        CGImageGetBitsPerComponent(maskRef),
        CGImageGetBitsPerPixel(maskRef),
        CGImageGetBytesPerRow(maskRef),
        CGImageGetDataProvider(maskRef), NULL, false);

    CGImageRef maskedImageRef = CGImageCreateWithMask([self CGImage], mask);
    UIImage *maskedImage = [UIImage imageWithCGImage:maskedImageRef];

    CGImageRelease(mask);
    CGImageRelease(maskedImageRef);

    return maskedImage;
    }

只是创建(我的意思是在photoshop中)一个png面具,并熟悉这个过程。

我鼓励你先掌握这个过程......

以下是有助于......的关键类别。

-(UIImage *)becomeSquare
    {
    CGSize imageSize = self.size;
    CGFloat width = imageSize.width;
    CGFloat height = imageSize.height;

    UIImage *result = self;

    if (width != height)
        {
        CGFloat newDimension = MIN(width, height);
        CGFloat widthOffset = (width - newDimension) / 2;
        CGFloat heightOffset = (height - newDimension) / 2;

        UIGraphicsBeginImageContextWithOptions(
            CGSizeMake(newDimension, newDimension), NO, 0. );

        [result drawAtPoint:CGPointMake(-widthOffset, -heightOffset)
            blendMode:kCGBlendModeCopy alpha:1. ];
        result = UIGraphicsGetImageFromCurrentImageContext();
        UIGraphicsEndImageContext();
        }

    return result;
    }

还有几个......

-(UIImage *)doScale
    {
    UIImage *result = self;

    CGSize size = CGSizeMake(320,320);
    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
    [result drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)];
    result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return result;
    }

-(UIImage *)scaled640AnyShape
    {
    if ( self.size.height < 5.0 ) return nil;
    if ( self.size.width < 5.0 ) return nil;

    UIImage *result = self;

    float widthShouldBe = 640.0;
    float heightShouldBe = widthShouldBe * ( self.size.height / self.size.width );

    CGSize size = CGSizeMake( widthShouldBe ,heightShouldBe );

    UIGraphicsBeginImageContextWithOptions(size, NO, 0.0f);
    [result drawInRect:CGRectMake(0.0f, 0.0f, size.width, size.height)];
    result = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return result;
    }

(显然可以根据需要更改硬编码输出大小。)

请注意,您的最终结果将通过适当的顺序组合实现,例如:

yourImage = [yourImage doSquare];
yourImage = [yourImage doMask];

一旦你有了工作......

然后....

对于LITERALLY你问的问题,有很多关于例子的例子代码......例如,https://stackoverflow.com/a/13870097/294884

如您所见,您从根本上......

UIGraphicsBeginImageContextWithOptions(...);
UIBezierPath * path = [UIBezierPath
    bezierPathWithRoundedRect:imageRect cornerRadius:10.f];
[path addClip];
[yourImage drawInRect:imageRect];
... then ... UIGraphicsGetImageFromCurrentImageContext();
.. see the extensive code above for how to save it and so on.

您只需使用上面的缩放示例即可进行缩放。

另请注意,当您更改&#34;区域时,#34; ... https://stackoverflow.com/a/17884863/294884

这里是关键技术的一个例子......

-(UIImage *)squareAndSmall
    {
    // genius credits: https://stackoverflow.com/a/17884863/294884

    CGSize finalsize = CGSizeMake(640,640);

    CGFloat scale = MAX(
        finalsize.width/self.size.width,
        finalsize.height/self.size.height);
    CGFloat width = self.size.width * scale;
    CGFloat height = self.size.height * scale;

    // for example, the central area....
    CGRect imageRect = CGRectMake(
                  (finalsize.width - width)/2.0f,
                  (finalsize.height - height)/2.0f,
                  width, height);

    // or, the top area... CGRect imageRect = CGRectMake( 0, 0, width, height);

    UIGraphicsBeginImageContextWithOptions(finalsize, NO, 0);
    [self drawInRect:imageRect];
    UIImage *newImage = UIGraphicsGetImageFromCurrentImageContext();    
    UIGraphicsEndImageContext();
    return newImage;
    }

希望这一切都有帮助!

答案 1 :(得分:2)

Nimit Parekh发现这个blog post条目非常有趣,简洁易懂。

以下代码复制/粘贴到“viewcontroller.h”文件中:

#import &lt;UIKit/UIKit.h&gt;

@interface UIImagePickerDemoViewController : UIViewController&lt; UIImagePickerControllerDelegate, UINavigationControllerDelegate&gt;

@property(nonatomic,retain) UIImagePickerController *imgPicker;
@property(nonatomic,retain) IBOutlet UIImageView *image_view;

//- (UIImage*)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)rect;
- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage;
@end

将代码复制/粘贴到“viewcontroller.m”文件中:

// Following method is use for the mask the image.

- (UIImage*) maskImage:(UIImage *)image withMask:(UIImage *)maskImage {

    CGImageRef maskRef = maskImage.CGImage; 

    CGImageRef mask = CGImageMaskCreate(CGImageGetWidth(maskRef),
                                        CGImageGetHeight(maskRef),
                                        CGImageGetBitsPerComponent(maskRef),
                                        CGImageGetBitsPerPixel(maskRef),
                                        CGImageGetBytesPerRow(maskRef),
                                        CGImageGetDataProvider(maskRef), NULL, false);

    CGImageRef masked = CGImageCreateWithMask([image CGImage], mask);
    return [UIImage imageWithCGImage:masked];
}

// Following method is use for Cropping the image for a perticular size.

- (UIImage*)imageByCropping:(UIImage *)imageToCrop toRect:(CGRect)rect
{
    UIGraphicsBeginImageContext(rect.size);
    CGContextRef currentContext = UIGraphicsGetCurrentContext();

    CGContextTranslateCTM(currentContext, 0.0, rect.size.height);
    CGContextScaleCTM(currentContext, 1.0, -1.0);   

    CGRect clippedRect = CGRectMake(0, 0, rect.size.width, rect.size.height);
    CGContextClipToRect( currentContext, clippedRect);
    CGRect drawRect = CGRectMake(rect.origin.x * -1,rect.origin.y * -1,imageToCrop.size.width,imageToCrop.size.height);
    CGContextDrawImage(currentContext, drawRect, imageToCrop.CGImage);
    CGContextScaleCTM(currentContext, 1.0, -1.0);

    UIImage *cropped = UIGraphicsGetImageFromCurrentImageContext();
    UIGraphicsEndImageContext();
    return cropped;
}

// Calling the method of maskimage.

//=============================Camera Enable(display)============================================
-(IBAction)next:(id)sender{

    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        self.imgPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    }
    [self presentModalViewController:self.imgPicker animated:YES];
}

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
    [picker dismissModalViewControllerAnimated:YES];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [picker dismissModalViewControllerAnimated:YES];
    UIImage *img =  [info objectForKey:@"UIImagePickerControllerOriginalImage"];
        self.image_view.image=[self maskImage:img withMask:[UIImage imageNamed:@"frame.png"]];
}
//===============================================================================================

// Calling the method of cropping the image.

//=============================Camera Enable(display)============================================
-(IBAction)next:(id)sender{

    if ([UIImagePickerController isSourceTypeAvailable:UIImagePickerControllerSourceTypeCamera]) {
        self.imgPicker.sourceType = UIImagePickerControllerSourceTypeCamera;
    }
    [self presentModalViewController:self.imgPicker animated:YES];
}

-(void)imagePickerControllerDidCancel:(UIImagePickerController *)picker{
    [picker dismissModalViewControllerAnimated:YES];
}

- (void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info {
    [picker dismissModalViewControllerAnimated:YES];
    UIImage *img =  [info objectForKey:@"UIImagePickerControllerOriginalImage"];
    self.image_view.image = [self imageByCropping:img toRect:CGRectMake(0, 0, 420, 40)];
}
//===============================================================================================

输出:

iPhone output

Grab the source code here.

答案 2 :(得分:0)

我有完全相同的个人资料图像选择控制器。这是我的委托代码。我不认为你需要一切,但你可以在这里找到一些有用的信息

-(void)imagePickerController:(UIImagePickerController *)picker didFinishPickingMediaWithInfo:(NSDictionary *)info
{
    NSString *mediaType = info[UIImagePickerControllerMediaType];

    if([mediaType isEqualToString:(NSString *) kUTTypeImage]) {

        UIImage *image = info[UIImagePickerControllerOriginalImage];
        UIImage *editedImage = (UIImage *) [info objectForKey:UIImagePickerControllerEditedImage];
        CGRect croppingRect = [info[UIImagePickerControllerCropRect] CGRectValue];

        if (editedImage) {
            image = editedImage;
        } else {
            CGFloat smaller = 1;
            if (SYSTEM_VERSION_GREATER_THAN_OR_EQUAL_TO(@"7.0")) {
                smaller = 0.9;
            }

            CGFloat width = MIN(image.size.width * smaller, image.size.height * (smaller * 0.95));
            croppingRect = CGRectMake(0 + (image.size.width - width) / 2,
                                      0 + (image.size.height - width) / 2,
                                      width, width);
        }

        UIImage *finalImage = nil;
        if (editedImage) {
            finalImage = [UIImage image:editedImage byScalingAndCroppingForSize:kCroppedImageSize];
        } else {
            finalImage = [UIImage image:image byScalingAndCroppingForSize:kCroppedImageSize];
        }

        if ([self.imagePickerDelegate respondsToSelector:@selector(profileImagePicker:didSelectImage:)]) {
            [self.imagePickerDelegate profileImagePicker:self didSelectImage:finalImage];
        } else {
            NSAssert(nil, @"Delegate should confirm ProfileImagePickerControllerDelegate protocol");
        }

    } else if ([mediaType isEqualToString:(NSString *) kUTTypeVideo]) {
        NSAssert(nil, @"Movie is not supported");
    }
}