cover_image

iOS 不规则(多边形)图形切图

Cocoa开发者社区 2018年03月28日 01:02

效果如下:


图片

Untitled.gif


研究背景


最近在做一个和人脸识别有关的


把人脸的眉毛、眼睛、鼻子等切出来  (后来改成只切一张人脸)


解决方法


第三方人脸识别的SDK会返回一些点给我们,如下图所示 


然后用这些坐标绘制一个不规则的图像


最后用这个不规则的图像做遮罩层,把图片切出来


如果有需要  保存不规则图片的大小就好,把空白的去掉,那就要再写多一步,原理相同


图片

image.png


多边形切图代码


- (UIImage *) cropImageWithImageV:(UIImageView *)imageV pointArr:(NSMutableArray *)pointArr {

     

    CGRect rect = CGRectZero;

    rect.size = imageV.image.size;

     

    UIGraphicsBeginImageContextWithOptions(rect.size, YES, 0.0);

     

    [[UIColor blackColor] setFill];

    UIRectFill(rect);

    [[UIColor whiteColor] setFill];

     

    UIBezierPath *aPath = [UIBezierPath bezierPath];

     

    //起点

    NSValue * v = pointArr[0];

    CGPoint p = [v CGPointValue];

    CGPoint m_p = [self convertCGPoint:p fromRect1:imageV.frame.size toRect2:imageV.frame.size];

    [aPath moveToPoint:m_p];

     

    //其他点

    for (int i = 1; i< pointArr.count; i++) {

        NSValue * v1 = pointArr[i];

        CGPoint p1 = [v1 CGPointValue];

        CGPoint m_p = [self convertCGPoint:p1 fromRect1:imageV.frame.size toRect2:imageV.frame.size];

        [aPath addLineToPoint:m_p];

    }

     

    [aPath closePath];

    [aPath fill];

     

    //遮罩层

    UIImage *mask = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

     

    UIGraphicsBeginImageContextWithOptions(rect.size, NO, 0.0);

     

    CGContextClipToMask(UIGraphicsGetCurrentContext(), rect, mask.CGImage);

    [imageV.image drawAtPoint:CGPointZero];

     

    UIImage *maskedImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

     

    return maskedImage;

}

- (CGPoint)convertCGPoint:(CGPoint)point1 fromRect1:(CGSize)rect1 toRect2:(CGSize)rect2 {

    point1.y = rect1.height - point1.y;

    CGPoint result = CGPointMake((point1.x*rect2.width)/rect1.width, (point1.y*rect2.height)/rect1.height);

    return result;

}


而如果你需要把空白的去掉 只保留有内容的图片大小就好,则要求 包含所有点的最小矩形 或直接求多边形 直接求多边形的算法我还没去研究 现在我只需要一个矩形就可以了


最小矩形算法


//算出包含数组里所有点的最小矩形

- (CGRect)returnMinRectangleWith:(NSMutableArray <nsvalue *> *)arr {

     

    if (arr.count<=0) return CGRectZero;

     

    NSValue * tempValue = arr[0];

    CGPoint tempP = [tempValue CGPointValue];

    CGFloat xMin = tempP.x;

    CGFloat xMax = tempP.x;

    CGFloat yMin = tempP.y;

    CGFloat yMax = tempP.y;

     

    for (int i = 1; i< arr.count; i++) {

         

        NSValue * value = arr[I];

         

        CGPoint p = [value CGPointValue];

         

        if (p.x > xMax) xMax = p.x;

        if (p.x < xMin) xMin = p.x;

        if (p.y > yMax) yMax = p.y;

        if (p.y < yMin) yMin = p.y;

         

    }

     

    return CGRectMake(xMin, yMin, xMax-xMin, yMax-yMin);

     

}</nsvalue *>


切割图片


//缩小图片

- (UIImage *)screenshotWithRect:(CGRect)rect imageView:(UIImageView *)imageV {

     

    UIGraphicsBeginImageContextWithOptions(rect.size, NO, [UIScreen mainScreen].scale);

     

    CGContextRef context = UIGraphicsGetCurrentContext();

    if (context == NULL) return nil;

     

    CGContextSaveGState(context);

    CGContextTranslateCTM(context, -rect.origin.x, -rect.origin.y);

     

    if( [self respondsToSelector:@selector(drawViewHierarchyInRect:afterScreenUpdates:)])

    {

        [imageV drawViewHierarchyInRect:imageV.bounds afterScreenUpdates:NO];

    }

    else

    {

        [imageV.layer renderInContext:context];

    }

     

    CGContextRestoreGState(context);

     

    UIImage *image = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

     

    return image;

}


作者:李境沛

链接:https://www.jianshu.com/p/4c47ac91c85f


更多推荐:


图片

继续滑动看下一个
Cocoa开发者社区
向上滑动看下一个