将图像裁剪为叠加层形状-iOS [英] Cropping an Image to the shape of an Overlay - 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屋!