2012-10-31 117 views
23

我想从UIBezierpath封闭的路径中获取图像(请参阅图像)。我使用drawRect方法在UIView上绘制图像,并且还绘制了使用drawRect方法的线条。 如何获得特定的封闭路径图像?请帮帮我。提前致谢。如何使用UIBezierPath裁剪图像?

此代码用于绘制贝塞尔路径。

UIBezierPath *aPath = [UIBezierPath bezierPath]; 
for (NSString *pointString in pointArray) { 
    if ([pointArray indexOfObject:pointString] == 0) 
     [aPath moveToPoint:CGPointFromString(pointString)]; 
    else 
     [aPath addLineToPoint:CGPointFromString(pointString)]; 
} 
[aPath closePath]; 

enter image description here

+0

我们如何可以借鉴的UIImageView一条线,当我尝试借鉴UIView的一个线路工作正常,但在UIImageView的不工作,你能不能帮我请 – dineshprasanna

+0

玛尼你实现了你的目标吗? – amar

+0

嗨,你可以回答你自己的问题.... – Rajneesh071

回答

14

您可以使用一个shapeLayer。喜欢的东西,

UIBezierPath *aPath = [UIBezierPath bezierPath]; 
for (NSString *pointString in pointArray) { 
    if ([pointArray indexOfObject:pointString] == 0) 
     [aPath moveToPoint:CGPointFromString(pointString)]; 
    else 
     [aPath addLineToPoint:CGPointFromString(pointString)]; 
} 
[aPath closePath]; 

CAShapeLayer *shapeLayer = [CAShapeLayer layer]; 
shapeLayer.path = aPath.CGPath; 
[view.layer setMask:shapeLayer];//or make it as [imageview.layer setMask:shapeLayer]; 
//and add imageView as subview of whichever view you want. draw the original image 
//on the imageview in that case 

为了得到它作为一个图像,

UIGraphicsBeginImageContext(view.bounds.size); 
[view.layer renderInContext:UIGraphicsGetCurrentContext()]; 
UIImage *image = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 

image应该有相应的图像。

+0

谢谢ACB ...如何从UIBezierpath中获取图像。 – Mani

+0

更新了我的答案。核实。 – iDev

+0

谢谢...我试过这个,它得到的图像和背景是白色的。我只需要UIBezier路径部分的图像(请参阅图像猫头部)。你明白我的意思? – Mani

1

如果您绘制代码一切都只是用 - addClip,即:

UIBezierPath *aPath = [UIBezierPath bezierPath]; 
for (NSString *pointString in pointArray) { 
    if ([pointArray indexOfObject:pointString] == 0) 
     [aPath moveToPoint:CGPointFromString(pointString)]; 
    else 
     [aPath addLineToPoint:CGPointFromString(pointString)]; 
} 
[aPath closePath]; 


CGContextSaveGState(context); 
{ 
    [aPath addClip]; 
    // draw image 
    [aPath stroke]; 
} 
CGContextRestoreGState(context); 
+0

嗨,高加密...谢谢你的回复。 – Mani

+0

如何从特定的UIBezierPath获取图像。 – Mani

+0

创建一个图像上下文并使用'UIGraphicsGetImageFromCurrentImageContext()' – hypercrypt

3

嗯,有几个是你必须要在通知的事情。

  1. 你传递你的UIImageView而不是你的UIView?
  2. 如果您是,是否启用了图像视图以进行触摸处理?
  3. 继承你的UIImageView并使用drawrect()为你处理这些东西。

如果你只想要图像的一部分(如猫),那么你需要按照UIBezierPath来掩盖图像。

更新

下面是一个完整的工作示例,将其更改为您的要求。

ViewController.h:

@interface ViewController : UIViewController 
{ 
    UIBezierPath *aPath; 
} 
@property (nonatomic,retain) NSMutableArray *pathArray; 
@property (nonatomic,retain) NSMutableDictionary *dic; 
@property (nonatomic,retain) IBOutlet UIImageView *imgView; 

@end 

ViewController.m:

@interface ViewController() 
- (IBAction)Crop:(id)sender; 
@end 

@implementation ViewController 
@synthesize pathArray,dic,imgView; 
- (void)viewDidLoad 
{ 
    [super viewDidLoad]; 

} 
- (void) setClippingPath:(UIBezierPath *)clippingPath : (UIImageView *)imgView; 
{ 

    NSLog(@"Mask Paths %@",clippingPath); 

    CAShapeLayer *maskLayer = [CAShapeLayer layer]; 
    maskLayer.frame = self.imgView.frame; 
    maskLayer.path = [clippingPath CGPath]; 
    maskLayer.fillColor = [[UIColor whiteColor] CGColor]; 
    maskLayer.backgroundColor = [[UIColor clearColor] CGColor]; 


    self.imgView.layer.mask = maskLayer; 



} 
-(void)touchesBegan:(NSSet *)touches withEvent:(UIEvent *)event 
{ 

    UITouch *mytouch=[[touches allObjects] objectAtIndex:0]; 
    self->aPath = [[UIBezierPath alloc]init]; 
    [aPath moveToPoint:[mytouch locationInView:imgView]]; 

} 
-(void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event 
{ 

    UITouch *mytouch=[[touches allObjects] objectAtIndex:0]; 
    [aPath addLineToPoint:[mytouch locationInView:imgView 
         ]]; 

} 
-(void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 
{ 

} 
- (IBAction)Crop:(id)sender 
{ 
    [self setClippingPath:aPath :imgView]; 
} 
+0

嗨,现在我们该如何将这个图层保存为背景清晰的uiimage?我尝试将CALayer self.imgView.layer.mask转换为UIImage,如http://stackoverflow.com/questions/3454356/uiimage-from-calayer-iphone-sdk中所述。但这不是理想的结果。 – ScarletWitch

+0

你好umer sufyan。我如何开始了解uibezierpath?我试图阅读文档,但因为我只是一个新手,我很难找到一个握手。请指导我一些很好的uibezierpath教程。谢谢。 – UsamaMan

+0

它迟了一点,但你应该渲染你的图层,并获得所需的UIImage .. –

0

这个工作对我来说...

UIBezierPath *path = ....//your path 
CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB(); 
CGContextRef context = CGBitmapContextCreate(nil, frame.size.width, frame.size.height, 8, 4*frame.size.width, colorSpace, (CGBitmapInfo)kCGImageAlphaPremultipliedFirst); 

CGContextAddPath(context, path.CGPath); 
CGContextClip(context); 
CGContextDrawImage(context, frame, image.CGImage); 

[UIImage imageWithCGImage:CGBitmapContextCreateImage(context)]; 
2

使用该吊舱ios-helpers

- (UIImage *)imageWithStrokeColor: (UIColor *)stroke_color andFillColor: (UIColor *)fill_color { 

    // adjust bounds to account for extra space needed for lineWidth 
    CGFloat width = self.bounds.size.width + self.lineWidth * 2; 
    CGFloat height = self.bounds.size.height + self.lineWidth * 2; 
    CGRect bounds = CGRectMake(self.bounds.origin.x, self.bounds.origin.y, width, height); 

    // create a view to draw the path in 
    UIView *view = [[UIView alloc] initWithFrame:bounds]; 

    // begin graphics context for drawing 
    UIGraphicsBeginImageContextWithOptions(view.frame.size, NO, [[UIScreen mainScreen] scale]); 

    // configure the view to render in the graphics context 
    [view.layer renderInContext:UIGraphicsGetCurrentContext()]; 

    // get reference to the graphics context 
    CGContextRef context = UIGraphicsGetCurrentContext(); 

    // reverse the y-axis to match the opengl coordinate space 
    CGContextScaleCTM(context, 1, -1); 
    CGContextTranslateCTM(context, 0, -view.bounds.size.height); 

    // translate matrix so that path will be centered in bounds 
    CGContextTranslateCTM(context, -(bounds.origin.x - self.lineWidth), -(bounds.origin.y - self.lineWidth)); 

    // stroke color 
    [stroke_color setStroke]; 
    [self stroke]; 

    //fill color 
    [fill_color setFill]; 
    [self fill]; 

    // get an image of the graphics context 
    UIImage *viewImage = UIGraphicsGetImageFromCurrentImageContext(); 

    // end the context 
    UIGraphicsEndImageContext(); 

    return viewImage; 
} 
+1

你可以添加更多的细节到你的答案?包含指向文档和示例代码的链接是很好的,但是您能描述它到底是什么吗? – bjb568

+0

@ bjb568,对不起。这是代码。 – Yijun

+0

好多了。 +1。 – bjb568

1

对于斯威夫特试试这个:ZImageCropper

ZImageCropper是使用下面的东西作为核心部件:

  • UIBezierPath
  • UITouch事件
  • CAShapeLayer
  • CoreGraphics在
0

IDEV的答案是优秀的,但如果你需要透明的背景,那么除了 UIGraphicsBeginImageContext(view.bounds.size); 你应该使用

UIGraphicsBeginImageContextWithOptions(view.bounds.size, NO, 1.0); 

默认情况下,图像内容创建与不透明== YES,所以你必须改变它为NO。

0
// This Work 100% 

- (无效)的touchesBegan:(NSSet中*)触摸withEvent:方法(的UIEvent *)事件{

mouseSwiped = NO; 
UITouch *touch = [touches anyObject]; 
lastPoint = [touch locationInView:self.view]; 
megView = [[UIImageView alloc]initWithFrame:CGRectMake(lastPoint.x , lastPoint.y , k_POINT_WIDTH , k_POINT_WIDTH)]; 
//[megView setImage:[UIImage imageNamed:@"b_image22.png"]]; 
[megView setContentMode:UIViewContentModeScaleToFill]; 
megView.alpha = 2; 
//megView.layer.backgroundColor = [UIColor whiteColor].CGColor; 
//megView.layer.cornerRadius = megView.frame.size.width/2; 
megView.clipsToBounds = YES; 
[self.main_uiview addSubview:megView]; 


self.bezierPath = [UIBezierPath bezierPath]; 
[self.bezierPath moveToPoint:lastPoint]; 

}

// Touchmove method 


- (void)touchesMoved:(NSSet *)touches withEvent:(UIEvent *)event { 

mouseSwiped = YES; 
UITouch *touch = [touches anyObject]; 
CGPoint currentPoint = [touch locationInView:self.view]; 
UIGraphicsBeginImageContext(self.main_uiview.frame.size); 
[self.bg_imageview.image drawInRect:CGRectMake(0, 0, self.main_uiview.frame.size.width, self.main_uiview.frame.size.height)]; 
megView.frame = CGRectMake(currentPoint.x - k_POINT_WIDTH/2 , currentPoint.y - k_POINT_WIDTH/2 , k_POINT_WIDTH , k_POINT_WIDTH); 
CGContextMoveToPoint(UIGraphicsGetCurrentContext(), lastPoint.x, lastPoint.y); 
CGContextAddLineToPoint(UIGraphicsGetCurrentContext(), currentPoint.x, currentPoint.y); 
CGContextSetLineCap(UIGraphicsGetCurrentContext(), kCGLineCapRound); 
CGContextStrokePath(UIGraphicsGetCurrentContext()); 


CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), red,green ,blue, 0.20); 
CGContextSetBlendMode(UIGraphicsGetCurrentContext(), kCGBlendModeCopy); 
    self.bg_imageview.image = UIGraphicsGetImageFromCurrentImageContext(); 
    [self.bg_imageview setAlpha:opacity]; 

UIGraphicsEndImageContext(); 

lastPoint = currentPoint; 

[self.bezierPath addLineToPoint:lastPoint]; 

}

// TouchEnd Method 


    - (void)touchesEnded:(NSSet *)touches withEvent:(UIEvent *)event 

{

[megView removeFromSuperview]; 

}

 // Image Crop Method 


    -(UIImage *)croppedImage 
    { 
UIImage *myImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
[self.bezierPath closePath]; 
CGContextSetRGBStrokeColor(UIGraphicsGetCurrentContext(), 0.0, 0.0, 0.0, 0.0); 
_b_image = self.bg_imageview.image; 
CGSize imageSize = _b_image.size; 
CGRect imageRect = CGRectMake(0, 0, imageSize.width, imageSize.height); 
UIGraphicsBeginImageContextWithOptions(imageSize, NO, [[UIScreen mainScreen] scale]); 
[self.bezierPath addClip]; 
[_b_image drawInRect:imageRect]; 

UIImage *croppedImage = UIGraphicsGetImageFromCurrentImageContext(); 
UIGraphicsEndImageContext(); 
return croppedImage; 

}