如何在Swift中创建一个IBDesignable图像下采样函数?

rkttyhzu  于 2023-09-30  发布在  Swift
关注(0)|答案(1)|浏览(88)

我面临的问题与图像使用太多的内存时,运行应用程序。一个905 kb的SVG图像在呈现时占用了大约150 mb,并且该图像正在被系统缓存。在不同的页面上加载几个不同的SVG图像会导致内存压力问题。
所以我开始研究图像降采样并找到了解决方案。我设法创建了一个函数来根据图像的大小对图像进行下采样(有帮助)。目前,我可以通过使用一个下采样器类来对图像进行下采样,该类需要设置为我想要启用下采样的每个imageView的自定义类。

但是我正在尝试为UIImageView创建一个IBDesignable扩展,这样我就可以使用任何自定义类,但仍然可以获得图像降采样的好处。

这是下采样类的代码

import UIKit

class DownsamplingImageView: UIImageView {
    
    @IBInspectable
    var downSample: Bool = true {
        didSet {
            setNeedsLayout()
        }
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        if downSample, let image = self.image {
            let targetSize = self.bounds.size
            let downsampledImage = image.downsample(to: targetSize)
            self.image = downsampledImage
        }
    }
}

extension UIImage {
    
    func downsample(to targetSize: CGSize) -> UIImage? {
        let sourceSize = self.size
        let widthRatio = targetSize.width / sourceSize.width
        let heightRatio = targetSize.height / sourceSize.height
        let scaleFactor = max(widthRatio, heightRatio)
        
        let scaledSize = CGSize(width: sourceSize.width * scaleFactor, height: sourceSize.height * scaleFactor)
        
        UIGraphicsBeginImageContextWithOptions(scaledSize, false, 0.0)
        self.draw(in: CGRect(origin: CGPoint.zero, size: scaledSize))
        let downsampledImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return downsampledImage
    }
}

这就是我如何尝试做一个扩展,但不幸的是它不工作。

import UIKit
@IBDesignable
extension UIImageView {
    
    @IBInspectable
    var downSample: Bool {
        get {
            return image != nil
        }
        set {
            setNeedsLayout()
        }
    }
    
    override open func layoutSubviews() {
        super.layoutSubviews()
        
        if downSample, let image = self.image {
            let targetSize = self.bounds.size
            let downsampledImage = image.downsample(to: targetSize)
            self.image = downsampledImage
        }
    }
}

extension UIImage {
    
    func downsample(to targetSize: CGSize) -> UIImage? {
        let sourceSize = self.size
        let widthRatio = targetSize.width / sourceSize.width
        let heightRatio = targetSize.height / sourceSize.height
        let scaleFactor = max(widthRatio, heightRatio)
        
        let scaledSize = CGSize(width: sourceSize.width * scaleFactor, height: sourceSize.height * scaleFactor)
        
        UIGraphicsBeginImageContextWithOptions(scaledSize, false, 0.0)
        self.draw(in: CGRect(origin: CGPoint.zero, size: scaledSize))
        let downsampledImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return downsampledImage
    }
}

有人能帮助或解释为什么UIImageView上的扩展不工作,但使用自定义类的作品?还有,有没有办法让扩展工作?
PS:150 MB的使用减少到只有6 MB的使用,幸运的是它被释放的权利,当用户离开页面!如果有人想启用下采样,第一个代码可以很好地工作,你所要做的就是将UIImageView自定义类设置为DownsamplingImageView

km0tfn4u

km0tfn4u1#

我最终使用了一个图像下采样器来解决这个问题。

import UIKit

class DownsamplingImageView: UIImageView {
    
    @IBInspectable
    var downSample: Bool = true {
        didSet {
            setNeedsLayout()
        }
    }
    
    override func layoutSubviews() {
        super.layoutSubviews()
        
        if downSample, let image = self.image {
            let targetSize = self.bounds.size
            let downsampledImage = image.downsample(to: targetSize)
            self.image = downsampledImage
        }
    }
}

extension UIImage {
    
    func downsample(to targetSize: CGSize) -> UIImage? {
        let sourceSize = self.size
        let widthRatio = targetSize.width / sourceSize.width
        let heightRatio = targetSize.height / sourceSize.height
        let scaleFactor = max(widthRatio, heightRatio)
        
        let scaledSize = CGSize(width: sourceSize.width * scaleFactor, height: sourceSize.height * scaleFactor)
        
        UIGraphicsBeginImageContextWithOptions(scaledSize, false, 0.0)
        self.draw(in: CGRect(origin: CGPoint.zero, size: scaledSize))
        let downsampledImage = UIGraphicsGetImageFromCurrentImageContext()
        UIGraphicsEndImageContext()
        
        return downsampledImage
    }
}

答:我忘了这是从哪里来的。我只是在回答这个问题,以防有人面临同样的问题。原始所有者的信贷。

相关问题