如何在iOS中对ImageView进行六边形图像遮罩处理?

3

我希望在iOS的ImageView上实现图像掩蔽。图像掩蔽应该是具有圆角的六边形。有些第三方代码是可用的,但他们没有圆角。

请帮忙。因为我是iOS的新手。


请查看https://dev59.com/gIHba4cB1Zd3GeqPSo3K#24770675以获取六边形蒙版(它实际上是推广到任何正多边形)。 - Rob
1个回答

5

根据您显示图像的方式,可以以几种不同的方式对其进行遮罩。

情况1:CALayer

您可以使用CALayer上的mask属性。此属性是CALayer*类型,并将适当地将目标层掩蔽到给定层的alpha通道。请注意,此属性可以是CALayer的子类,特别是CAShapeLayer,它允许您为掩蔽指定直接路径(在这里,您可以指定六边形)。还要注意,在掩蔽层上设置一些不透明颜色,以使掩蔽层实际上成为掩蔽。

注意:如果您需要绘制六边形的路径,请告诉我,因为我今天早些时候刚刚做了几何运算:D

情况2:CoreGraphics

您可以像这样使用CGImageMaskCreateCGImageCreateWithMask

- (UIImage *)maskImage:(UIImage *)image withMask:(UIImage *)mask {

  CGImageRef cgmask = CGImageMaskCreate(CGImageGetWidth(mask.CGImage), CGImageGetHeight(mask.CGImage), CGImageGetBitsPerComponent(mask.CGImage), CGImageGetBitsPerPixel(mask.CGImage), CGImageGetBytesPerRow(mask.CGImage), CGImageGetDataProvider(mask.CGImage), NULL, false);
  CGImageRef cgmaskedImage = CGImageCreateWithMask(image.CGImage, cgmask);
  UIImage *retval = [UIImage imageWithCGImage:maskedImageRef];
  CGImageRelease(cgmask);
  CGImageRelease(cgmaskedImage);

  return retval;
}

掩码图像应该在您想要掩盖的部分为黑色。这样,您可以在Photoshop中创建一个六边形,然后使用此方法创建掩蔽图像。好处是,如果需要,它将自动缩放掩码图像。
我个人更喜欢使用CALayers,因为即使UIImageView也由CALayer支持,而且我对CALayer相当熟悉。话虽如此,我不确定哪个更高效或者做法是否正确。
编辑:添加六边形绘制代码。
在这里,我将创建一些代码来创建一个CGPathRef,它将表示一个六边形。
  UIView *v = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
  v.backgroundColor = [UIColor purpleColor];

  CGRect rect = v.frame;

  CAShapeLayer *hexagonMask = [CAShapeLayer layer];
  UIBezierPath *hexagonPath = [UIBezierPath bezierPath];
  CGFloat sideWidth = 2 * ( 0.5 * rect.size.width / 2 );
  CGFloat lcolumn = ( rect.size.width - sideWidth ) / 2;
  CGFloat rcolumn = rect.size.width - lcolumn;
  CGFloat height = 0.866025 * rect.size.height;
  CGFloat y = (rect.size.height - height) / 2;
  CGFloat by = rect.size.height - y;
  CGFloat midy = rect.size.height / 2;
  CGFloat rightmost = rect.size.width;
  [hexagonPath moveToPoint:CGPointMake(lcolumn, y)];
  [hexagonPath addLineToPoint:CGPointMake(rcolumn, y)];
  [hexagonPath addLineToPoint:CGPointMake(rightmost, midy)];
  [hexagonPath addLineToPoint:CGPointMake(rcolumn, by)];
  [hexagonPath addLineToPoint:CGPointMake(lcolumn, by)];
  [hexagonPath addLineToPoint:CGPointMake(0, midy)];
  [hexagonPath addLineToPoint:CGPointMake(lcolumn, y)];

  hexagonMask.path = hexagonPath.CGPath;
  v.layer.mask = hexagonMask;

你可以将你的图片视图替换为v,它应该会自动遮罩。

编辑:带边框六边形的代码清单。请注意,在此示例中,lineWidth只会显示为2.5,因为它的一半将被裁剪掉。如果你想要一个真正的5像素边框,那么请将lineWidth指定为10

  UIView *v = [[UIView alloc] initWithFrame:CGRectMake(100, 100, 100, 100)];
  v.backgroundColor = [UIColor purpleColor];

  CGRect rect = v.frame;

  CAShapeLayer *hexagonMask = [CAShapeLayer layer];
  CAShapeLayer *hexagonBorder = [CAShapeLayer layer];
  hexagonBorder.frame = v.layer.bounds;
  UIBezierPath *hexagonPath = [UIBezierPath bezierPath];
  CGFloat sideWidth = 2 * ( 0.5 * rect.size.width / 2 );
  CGFloat lcolumn = ( rect.size.width - sideWidth ) / 2;
  CGFloat rcolumn = rect.size.width - lcolumn;
  CGFloat height = 0.866025 * rect.size.height;
  CGFloat y = (rect.size.height - height) / 2;
  CGFloat by = rect.size.height - y;
  CGFloat midy = rect.size.height / 2;
  CGFloat rightmost = rect.size.width;
  [hexagonPath moveToPoint:CGPointMake(lcolumn, y)];
  [hexagonPath addLineToPoint:CGPointMake(rcolumn, y)];
  [hexagonPath addLineToPoint:CGPointMake(rightmost, midy)];
  [hexagonPath addLineToPoint:CGPointMake(rcolumn, by)];
  [hexagonPath addLineToPoint:CGPointMake(lcolumn, by)];
  [hexagonPath addLineToPoint:CGPointMake(0, midy)];
  [hexagonPath addLineToPoint:CGPointMake(lcolumn, y)];

  hexagonMask.path = hexagonPath.CGPath;
  hexagonBorder.path = hexagonPath.CGPath;
  hexagonBorder.fillColor = [UIColor clearColor].CGColor;
  hexagonBorder.strokeColor = [UIColor blackColor].CGColor;
  hexagonBorder.lineWidth = 5;
  v.layer.mask = hexagonMask;
  [v.layer addSublayer:hexagonBorder];

请提供您用于绘制六边形的代码。谢谢 :-)。 - Darshan_Ethan
没问题,谢谢。关于圆角,我添加了两行代码。 view.layer.cornerRadius = 5; view.layer.masksToBounds = YES; - Darshan_Ethan
如何设置那个六边形的边框? - Darshan_Ethan
不行啊,它只在角落处显示边框,而不是整个边框。:( - Darshan_Ethan
请帮帮我。每当我提出正常问题时,大家都会投反对票。现在没有人能回答我的问题了。 - Darshan_Ethan
显示剩余2条评论

网页内容由stack overflow 提供, 点击上面的
可以查看英文原文,
原文链接