iOS UIImage蒙面边框

时间:2014-05-07 10:38:29

标签: ios objective-c uiimage core-graphics

在iOS中是否有办法为不是简单矩形的图像添加边框?

我使用以下代码成功着色图像:

- (UIImage *)imageWithTintColor:(UIColor *)tintColor
{
    UIGraphicsBeginImageContextWithOptions(self.size, NO, self.scale);

    CGContextRef context = UIGraphicsGetCurrentContext();

    CGContextTranslateCTM(context, 0, self.size.height);
    CGContextScaleCTM(context, 1.0, -1.0);
    CGContextSetBlendMode(context, kCGBlendModeNormal);

    CGRect rect = CGRectMake(0, 0, self.size.width, self.size.height);
    CGContextClipToMask(context, rect, self.CGImage);

    [tintColor setFill];
    CGContextFillRect(context, rect);

    UIImage *tintedImage = UIGraphicsGetImageFromCurrentImageContext();

    UIGraphicsEndImageContext();

    return tintedImage;
}

让我们说例如我想为此图像添加蓝色边框(注意:这不是'A'NSString,而是UIImage对象示例)

enter image description here

当我将上面的代码更改为[color setStroke]CGContextStrokeRect(context, rect)时,图像就会消失。

我已经从SO中了解到使用CoreImage + EdgeDetection可以实现这一点,但是没有“简单”的CoreGraphics - 类似于着色图像的方式吗?

谢谢!

- 编辑 -

请注意,我想为图像本身添加边框。我不想通过UIImageView创建边框效果!

在应用边框之前,边框应与图像的形状相匹配。 在这种情况下:'A'的外部+内部的蓝色轮廓。

5 个答案:

答案 0 :(得分:2)

这不是我所说的非常令人满意的方法,但在某种程度上有效。

您可以使用向图层添加阴影。为此,您需要剥离图像中的白色部分,使角色被alpha包围。

我使用了以下代码。

UIImage *image = [UIImage imageNamed:@"image_name_here.png"];

CALayer *imageLayer = [CALayer layer];
imageLayer.frame = CGRectMake(0, 0, 200.0f, 200.0f);
imageLayer.contents = (id)image.CGImage;
imageLayer.position = self.view.layer.position;

imageLayer.shadowColor = [UIColor whiteColor].CGColor;
imageLayer.shadowOffset = CGSizeMake(0.0f, 0.0f);
imageLayer.shadowOpacity = 1.0f;
imageLayer.shadowRadius = 4.0f;

[self.view.layer addSublayer:imageLayer];

结果将是这样的。

And the result would be

答案 1 :(得分:2)

我意识到这是2年前被问到的,可能与你无关,但是我想提交我的解决方案以防其他人在寻找答案的同时偶然发现这个问题(就像我刚才那样)

在图像周围生成边框的一种方法是将图像着色为边框颜色(比如黑色),然后将较小的图像副本覆盖在有色图像的中间。

我在imageWithTintColor:tintColor函数上构建了我的解决方案,作为 Swift 3 UIImage的扩展:

extension UIImage {

    func imageByApplyingBorder(ofSize borderSize: CGFloat, andColor borderColor: UIColor) -> UIImage {
        /* 
            Get the scale of the smaller image
            If borderSize is 10% then smaller image should be 90% of its original size
        */
        let scale: CGFloat = 1.0 - borderSize

        // Generate tinted background image of original size
        let backgroundImage = imageWithTintColor(borderColor)
        // Generate smaller image of scale
        let smallerImage = imageByResizing(by: scale)

        UIGraphicsBeginImageContext(backgroundImage.size)

        // Draw background image first, followed by smaller image in the middle
        backgroundImage.draw(at: CGPoint(x: 0, y: 0))
        smallerImage.draw(at: CGPoint(
            x: (backgroundImage.size.width - smallerImage.size.width) / 2,
            y: (backgroundImage.size.height - smallerImage.size.height) / 2
        ))

        let borderedImage = UIGraphicsGetImageFromCurrentImageContext()!

        UIGraphicsEndImageContext()

        return borderedImage
    }

    func imageWithTintColor(_ color: UIColor) -> UIImage {
        UIGraphicsBeginImageContext(size)
        let context = UIGraphicsGetCurrentContext()!

        // Turn up-side-down (later transformations turns image back)
        context.translateBy(x: 0, y: size.height)
        context.scaleBy(x: 1.0, y: -1.0)

        context.setBlendMode(.normal)

        // Mask to visible part of image (turns image right-side-up)
        context.clip(to: CGRect(x: 0, y: 0, width: size.width, height: size.height), mask: self.cgImage!)

        // Fill with input color
        color.setFill()
        context.fill(CGRect(x: 0, y: 0, width: size.width, height: size.height))

        let tintedImage = UIGraphicsGetImageFromCurrentImageContext()!

        UIGraphicsEndImageContext()

        return tintedImage
    }

    func imageByResizing(by scale: CGFloat) -> UIImage {
        // Determine new width and height
        let width = scale * size.width
        let height = scale * size.height

        // Draw a scaled down image
        UIGraphicsBeginImageContextWithOptions(CGSize(width: width, height: height), false, 0.0)
        draw(in: CGRect(x: 0, y: 0, width: width, height: height))
        let newImage = UIGraphicsGetImageFromCurrentImageContext()!
        UIGraphicsEndImageContext()

        return newImage
    }

}

请注意 borderSize imageByApplyingBorder:ofSize:andColor: 参数以原始图片大小的百分比形式给出。如果您的图片是 100x100 px borderSize = 0.1 ,那么您的图片会显示 100x100 px 使用 10x10 px 内部边框。*

以下是使用上述功能在iOS模拟器照片之一的1000x1000px圆形中心剪辑上生成的示例图像:

Example output

欢迎任何有关优化或其他方法的建议。

答案 2 :(得分:0)

您可以使用以下代码为UIImageView添加边框:

[self.testImage.layer setBorderColor:[UIColor blueColor].CGColor];
[self.testImage.layer setBorderWidth:5.0];

答案 3 :(得分:0)

试试这个

 #import <QuartzCore/QuartzCore.h>


 [yourUIImageView.layer setBorderColor:[UIColor blueColor].CGColor];

 [yourUIImageView.layer setBorderWidth:6.0];

答案 4 :(得分:0)

如果有人为UIImageView或任何其他视图查找外部透明边框,请查看我的解决方案herehere