ios - 如何快速向uiimage添加彩色边框

标签 ios swift image image-processing border

使用图层(borderWidth,borderColor等)向UIImageView添加边框非常容易。是否有可能在图像上添加边框,而不是在图像视图上添加边框?有人知道吗

更新:

我尝试遵循以下建议并使用extension。谢谢你,但是我没有得到理想的结果。这是我的代码。怎么了?

import UIKit
    class ViewController: UIViewController {

    var imageView: UIImageView!
    var sizeW = CGFloat()
    var sizeH = CGFloat()

    override func viewDidLoad() {
        super.viewDidLoad()

        sizeW = view.frame.width
        sizeH = view.frame.height

        setImage()
    }

    func setImage(){

        //add image view
        imageView = UIImageView(frame: CGRect(x: 0, y: 0, width: sizeW/2, height: sizeH/2))
        imageView.center = view.center
        imageView.tintColor = UIColor.orange
        imageView.contentMode = UIViewContentMode.scaleAspectFit

        let imgOriginal = UIImage(named: "plum")!.withRenderingMode(.alwaysTemplate)
        let borderImage = imgOriginal.imageWithBorder(width: 2, color: UIColor.blue)
        imageView.image = borderImage

        view.addSubview(imageView)

    }



}


    extension UIImage {
    func imageWithBorder(width: CGFloat, color: UIColor) -> UIImage? {
        let square = CGSize(width: min(size.width, size.height) + width * 2, height: min(size.width, size.height) + width * 2)
        let imageView = UIImageView(frame: CGRect(origin: CGPoint(x: 0, y: 0), size: square))
        imageView.contentMode = .center
        imageView.image = self
        imageView.layer.borderWidth = width
        imageView.layer.borderColor = color.cgColor
        UIGraphicsBeginImageContextWithOptions(imageView.bounds.size, false, scale)
        guard let context = UIGraphicsGetCurrentContext() else { return nil }
        imageView.layer.render(in: context)
        let result = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        return result
    }
}


第二个带有红色边框的图像或多或少是我所需要的:

enter image description here

enter image description here

最佳答案

这是我在Swift 4中编写的UIImage扩展。正如IOSDealBreaker所说,这全都与图像处理有关,并且可能会发生某些特殊情况。您应该拥有带有透明背景的png图像,并且如果尺寸大于原始尺寸,则应进行管理。


首先获取图像的彩色“阴影”版本。
然后在给定的原点周围绘制并重新绘制阴影图像(在我们的示例中,在(0,0)附近的距离为边框粗细)
在原点绘制源图像,使其显示在前景上。
如果边框超出了原始矩形,则可能需要放大图像。


我的方法使用许多util方法和类扩展。以下是一些数学运算,可以使向量(实际上是一个点)围绕另一个点旋转:Rotating a CGPoint around another CGPoint

extension CGPoint {
    func rotated(around origin: CGPoint, byDegrees: CGFloat) -> CGPoint {
        let dx = self.x - origin.x
        let dy = self.y - origin.y
        let radius = sqrt(dx * dx + dy * dy)
        let azimuth = atan2(dy, dx) // in radians
        let newAzimuth = azimuth + (byDegrees * CGFloat.pi / 180.0) // convert it to radians
        let x = origin.x + radius * cos(newAzimuth)
        let y = origin.y + radius * sin(newAzimuth)
        return CGPoint(x: x, y: y)
    }
}


我编写了自定义CIFilter来为具有透明背景的图像着色:Colorize a UIImage in Swift

class ColorFilter: CIFilter {
    var inputImage: CIImage?
    var inputColor: CIColor?
    private let kernel: CIColorKernel = {
        let kernelString =
        """
        kernel vec4 colorize(__sample pixel, vec4 color) {
            pixel.rgb = pixel.a * color.rgb;
            pixel.a *= color.a;
            return pixel;
        }
        """
        return CIColorKernel(source: kernelString)!
    }()

    override var outputImage: CIImage? {
        guard let inputImage = inputImage, let inputColor = inputColor else { return nil }
        let inputs = [inputImage, inputColor] as [Any]
        return kernel.apply(extent: inputImage.extent, arguments: inputs)
    }
}

extension UIImage {
    func colorized(with color: UIColor) -> UIImage {
        guard let cgInput = self.cgImage else {
            return self
        }
        let colorFilter = ColorFilter()
        colorFilter.inputImage = CIImage(cgImage: cgInput)
        colorFilter.inputColor = CIColor(color: color)

        if let ciOutputImage = colorFilter.outputImage {
            let context = CIContext(options: nil)
            let cgImg = context.createCGImage(ciOutputImage, from: ciOutputImage.extent)
            return UIImage(cgImage: cgImg!, scale: self.scale, orientation: self.imageOrientation).alpha(color.rgba.alpha).withRenderingMode(self.renderingMode)
        } else {
            return self
        }
    }


在这一点上,您应该拥有一切来完成这项工作:

extension UIImage {
    func stroked(with color: UIColor, size: CGFloat) -> UIImage {
        let strokeImage = self.colorized(with: color)
        let oldRect = CGRect(x: size, y: size, width: self.size.width, height: self.size.height).integral
        let newSize = CGSize(width: self.size.width + (2*size), height: self.size.height + (2*size))
        let translationVector = CGPoint(x: size, y: 0)

        UIGraphicsBeginImageContextWithOptions(newSize, false, self.scale)
        if let context = UIGraphicsGetCurrentContext() {
            context.interpolationQuality = .high

            let step = 10 // reduce the step to increase quality
            for angle in stride(from: 0, to: 360, by: step) {
                let vector = translationVector.rotated(around: .zero, byDegrees: CGFloat(angle))
                let transform = CGAffineTransform(translationX: vector.x, y: vector.y)
                context.concatenate(transform)
                context.draw(strokeImage.cgImage!, in: oldRect)
                let resetTransform = CGAffineTransform(translationX: -vector.x, y: -vector.y)
                context.concatenate(resetTransform)
            }
            context.draw(self.cgImage!, in: oldRect)

            let newImage = UIImage(cgImage: context.makeImage()!, scale: self.scale, orientation: self.imageOrientation)
            UIGraphicsEndImageContext()

            return newImage.withRenderingMode(self.renderingMode)
        }
        UIGraphicsEndImageContext()
        return self
    }
}

关于ios - 如何快速向uiimage添加彩色边框,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/56254185/

相关文章:

java - 如何从数据库中查看JSP页面中的多个图像?

c# - 将 PDF 转换为图像批处理

swift - 究竟是什么区分了 Swift 中的两个函数?

html - 大图像上的小图像悬停 css

iphone - 将应用程序发送到后台进程

ios - stringByAppending字符串问题

Swift:使用 array1 中的键和 array2 中的值构建一个字典

ios - UICollectionView header 上的 UITapGestureRecognizer 不起作用?

ios - 有没有办法设置模拟器在有限的内存上工作?

IOS 如何在 Collection View 中只下载合适的图片?