如何在图像中绘制线条而不是整个UIImageView?

时间:2016-01-11 11:35:23

标签: ios objective-c uiimageview uigesturerecognizer cashapelayer

在着色图像之前:

enter image description here

着色图像后:

enter image description here

这是我的代码:

-(void)touchesMoved:(NSSet<UITouch *> *)touches withEvent:(UIEvent *)event
{
    UITouch *touch = [[event allTouches] anyObject];
    touchPoint = [touch locationInView:self.imgColor];
    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
    [path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];
    startingPoint=touchPoint;
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = [path CGPath];
    shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
    shapeLayer.lineWidth = 3.0;
    shapeLayer.fillColor = [[UIColor redColor] CGColor];
    [self.imgColor.layer addSublayer:shapeLayer];
    [arrLayer addObject:shapeLayer];
    NSLog(@"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y);  
}

取决于用户触摸,它在UIImageView内画了一条线。

我需要的是:

如果图像尺寸很小,那么我不想在图像外部进行绘图。

在用户必须绘制的图像内,有什么办法吗?请建议我。

4 个答案:

答案 0 :(得分:1)

将此代码添加到您的触摸查看视图中。

override func pointInside(point: CGPoint, withEvent event: UIEvent?) -> Bool {
    return CGRectContainsPoint(doggyImage.frame, point)
}

答案 1 :(得分:0)

第一个评论if (!CGRectContainsPoint(doggyImage.frame, touchPoint))中提供的代码是一些条件,您可以使用它来检查触摸点是否在一个特定视图中,我认为您应该用它来与您的狗图像进行比较(我不知道它是哪个变量,所以我使用doggyImage。也许self.imgColor是正确的变量。)

对于最简单的解决方案,您至少需要做两件事

  • 如果在touchesBegan之外doggyImage,请勿执行任何操作,只需return
  • 防止从内到外绘制线条,因此请使用相同的条件,并应用touchesEnd中使用的相同代码来处理stopDrawLine之类的内容。

更高级的方法包括计算从触摸到图像的最近点(如果它在外面),并将其绘制在边缘上。

BTW,目前在您的touchesMoved中,您为每个触摸点创建了一个新的UIBezierPath,从而产生了数百个离散的小线条。您可能希望在path中的touchesBeganaddLineToPoint时尝试新touchesMoved。因此整条线路都在一条路上,因此您可以提供“撤消”这样的风险。

答案 2 :(得分:0)

取一个CGRect对象全局分配其值如下

 CGRect imagerect = CGRectMake(imgColor.center.x - (imgColor.image.size.width/2 + imgColor.frame.origin.x), imgColor.center.y - (imgColor.image.size.height/2+ imgColor.frame.origin.y), imgColor.image.size.width, imgColor.image.size.height);

现在在touchesMoved方法中,在绘制if( CGRectContainsPoint(imagerect, touchPoint))

之前设置了一个条件

所以方法就像

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

    UITouch *touch = [[event allTouches] anyObject];
      touchPoint = [touch locationInView:self.imgColor];


    if( CGRectContainsPoint(imagerect, touchPoint))
    {

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
    [path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];
    startingPoint=touchPoint;
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = [path CGPath];
    shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
    shapeLayer.lineWidth = 3.0;
    shapeLayer.fillColor = [[UIColor redColor] CGColor];
    [self.imgColor.layer addSublayer:shapeLayer];
    [arrLayer addObject:shapeLayer];
    NSLog(@"Touch moving point =x : %f Touch moving point =y : %f", touchPoint.x, touchPoint.y);
    }

}

答案 3 :(得分:0)

这可能不是完美的解决方案,但我会尝试与您的要求相同。请尝试使用此

#import "ViewController.h"

@interface ViewController ()
{
    CGPoint touchPoint,startingPoint;

    CALayer *layer;
    float x1;
    float y1;
    IBOutlet UIImageView *imgColor;
}
@end

@implementation ViewController

- (void)viewDidLoad {
    [super viewDidLoad];
    layer = [CALayer layer];
}

- (void)didReceiveMemoryWarning {
    [super didReceiveMemoryWarning];
}
-(void)viewDidAppear:(BOOL)animated
{

    CGSize scaledImageSize = imgColor.image.size;
    CGRect imageFrame = CGRectMake(roundf(0.5f*(CGRectGetWidth(imgColor.bounds)-scaledImageSize.width)), roundf(0.5f*(CGRectGetHeight(imgColor.bounds)-scaledImageSize.height)), roundf(scaledImageSize.width), roundf(scaledImageSize.height));
    x1 = imageFrame.origin.x ;
    y1 =  imageFrame.origin.y ;


}



- (UIColor*)getRGBAsFromImage:(UIImage*)image atX:(int)x andY:(int)y
{
    if (x < 0 || y<0  || x> image.size.width || y > image.size.height) {
        return nil;
    }
    // First get the image into your data buffer
    CGImageRef imageRef = [image CGImage];
    NSUInteger width = CGImageGetWidth(imageRef);
    NSUInteger height = CGImageGetHeight(imageRef);
    CGColorSpaceRef colorSpace = CGColorSpaceCreateDeviceRGB();
    unsigned char *rawData = (unsigned char*) calloc(height * width * 4, sizeof(unsigned char));
    NSUInteger bytesPerPixel = 4;
    NSUInteger bytesPerRow = bytesPerPixel * width;
    NSUInteger bitsPerComponent = 8;
    CGContextRef context = CGBitmapContextCreate(rawData, width, height,
                                                 bitsPerComponent, bytesPerRow, colorSpace,
                                                 kCGImageAlphaPremultipliedLast | kCGBitmapByteOrder32Big);
    CGColorSpaceRelease(colorSpace);

    CGContextDrawImage(context, CGRectMake(0, 0, width, height), imageRef);
    CGContextRelease(context);

    // Now your rawData contains the image data in the RGBA8888 pixel format.
    NSUInteger byteIndex = (bytesPerRow * y) + x * bytesPerPixel;

        CGFloat alpha = ((CGFloat) rawData[byteIndex + 3] ) / 255.0f;
        CGFloat red   = ((CGFloat) rawData[byteIndex]     ) / alpha;
        CGFloat green = ((CGFloat) rawData[byteIndex + 1] ) / alpha;
        CGFloat blue  = ((CGFloat) rawData[byteIndex + 2] ) / alpha;
        byteIndex += bytesPerPixel;
    if (red >= 0 || green >= 0 || blue >= 0) {
        return  [UIColor colorWithRed:red green:green blue:blue alpha:alpha];

    }
    return nil;
}

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

    UITouch *touch = [[event allTouches] anyObject];

    touchPoint = [touch locationInView:imgColor];

    ;
    if ([self getRGBAsFromImage:imgColor.image atX:touchPoint.x - x1 andY:touchPoint.y - y1] && !(touchPoint.x == 0 && touchPoint.y == 0)) {

    UIBezierPath *path = [UIBezierPath bezierPath];
    [path moveToPoint:CGPointMake(touchPoint.x,touchPoint.y)];
    [path addLineToPoint:CGPointMake(startingPoint.x,startingPoint.y)];
    startingPoint=touchPoint;
    CAShapeLayer *shapeLayer = [CAShapeLayer layer];
    shapeLayer.path = [path CGPath];
    shapeLayer.strokeColor = [[UIColor blueColor] CGColor];
    shapeLayer.lineWidth = 1.0;
    shapeLayer.fillColor = [[UIColor redColor] CGColor];


        [imgColor.layer addSublayer:shapeLayer];
    }

}
- (void)touchesEnded:(NSSet<UITouch *> *)touches withEvent:(nullable UIEvent *)event;
{
    touchPoint = CGPointMake(0, 0);
}
@end