将图像裁剪为叠加层形状-iOS [英] Cropping an Image to the shape of an Overlay - iOS

查看:109
本文介绍了将图像裁剪为叠加层形状-iOS的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

我正在使用pickerController的视图和uinavigationcontrollerdelegate如下添加叠加层.

I'm adding the overlay using pickerController's view and the uinavigationcontrollerdelegate as below.

-(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];

  }
}

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

When the overlay defined above is added, I tend to get this view:

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

I can crop the image exactly to a square using a defined CGRect.

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

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

如何解决存在圆形叠加层且imagePickers编辑属性为YES的问题?我可以放大和缩小图片.我如何在这里使用BezierPath?

How about approaching this problem where there is a circular overlay and imagePickers editing property is YES? I can zoom in and zoom out of the pic. How can i make use of the BezierPath here?

推荐答案

问题addClip的简短答案,但是您提到自己是一个初学者,所以这里是从A到Z的所有步骤!

the short answer to your question addClip , but you mention you're a beginner, so here's all the steps from A to Z!!

首先,尝试使用此类别,看看是否有帮助. (如果您不熟悉带有类别的Google,或者只是在此处提出评论.)

Firstly, try this category, see if it helps. (If you're not familiar w/ categories have a google or just ask here in a comment.)

-(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蒙版,并熟悉该过程即可.

just create (I mean in photoshop) a png mask, and get familiar with that process.

我鼓励您先掌握该过程...

I encourage you to master that process first...

关键类别将有助于...

Here are critical categories that will help...

-(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;
    }

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

(obviously change the hard-coded output sizes as you wish.)

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

Note that your final result, will be achieved, by a combination in the appropriate order, such as:

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

一旦您能够正常工作...

once you've got that working ...

对于您的要求,有很多关于..的示例代码,例如 https://stackoverflow.com/a /13870097/294884

for LITERALLY what you ask, there are many example codes about .. e.g., what about https://stackoverflow.com/a/13870097/294884

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

As you can see, you fundamentally...

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.

您只需要使用上面的缩放示例来正确缩放即可.

You just have to get the zoom right with the scaling examples above.

还要注意这一点,当您更改裁剪区域"时... https://stackoverflow.com/a/17884863/294884

Also note this, when you are changing the "area cropped"... https://stackoverflow.com/a/17884863/294884

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

here's an example of that critical technique...

-(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;
    }

希望这对您有帮助!

这篇关于将图像裁剪为叠加层形状-iOS的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆