SwiftUI生成缩略图
SwiftUI生成缩略图

SwiftUI生成缩略图

SwiftUI显示图片列表时,如果显示多张图片,可能会导致内存过大,产生卡顿。

例如,显示20张高清壁纸图片。

当显示缩略图时,内存在37MB左右。当显示原图时,内存在600MB左右。

注:1张普通图片重复显示无法对比内存取消,需要多张高清图片才可以看出内存的显著变化。

因此,在图片列表过多以及图片较大的场景中,需要显示缩略图。

生成缩略图

1、根据Data生成缩略图

调用generateThumbnail方法,传入Data类型的图片和设置的大小:

private func generateThumbnail(from data: Data, maxSize: CGFloat) -> NSImage? {
    guard let imageSource = CGImageSourceCreateWithData(data as CFData, nil),
          let cgImage = CGImageSourceCreateThumbnailAtIndex(
            imageSource,
            0,
            [
                kCGImageSourceCreateThumbnailFromImageAlways: true,
                kCGImageSourceThumbnailMaxPixelSize: maxSize,
                kCGImageSourceCreateThumbnailWithTransform: true
            ] as CFDictionary
          ) else {
        return nil
    }
    
    let size = NSSize(width: cgImage.width, height: cgImage.height)
    let thumbnail = NSImage(cgImage: cgImage, size: size)
    return thumbnail
}

SwiftUI生成缩略图:

if let original = NSImage(named: "文件\(i)"),
   let data = original.tiffRepresentation,
   let thumb = generateThumbnail(from: data, maxSize: 20) {
    ArrayImg.append(ImageItem(image: Image(nsImage: thumb)))
}

创建NSImage图片,传入generateThumbnail生成图片缩略图。

2、根据图片URL创建缩略图

传入图片的URL和尺寸,生成缩略图。

private func generateThumbnail(from url: URL, maxSize: CGFloat) -> NSImage? {
    guard let imageSource = CGImageSourceCreateWithURL(url as CFURL, nil),
          let cgImage = CGImageSourceCreateThumbnailAtIndex(
            imageSource,
            0,
            [
                kCGImageSourceCreateThumbnailFromImageAlways: true,
                kCGImageSourceThumbnailMaxPixelSize: maxSize,
                kCGImageSourceCreateThumbnailWithTransform: true
            ] as CFDictionary
          ) else {
        return nil
    }
    
    let size = NSSize(width: cgImage.width, height: cgImage.height)
    let thumbnail = NSImage(cgImage: cgImage, size: size)
    return thumbnail
}

与Data的区别在于,这里传入的是图片的URL。前者调用的是CGImageSourceCreateWithData创建CGImage,这里调用的是CGImageSourceCreateWithURL创建CGImage。

调用方法相同:

let thumb = generateThumbnail(from: url, maxSize: 20)

总结

对于压缩图片工具或展示图片列表时,需要考虑生成缩略图,防止图片过大造成内存过大的问题。

在实际使用中,还可以考虑懒加载图片。例如:

// 懒加载缩略图
private var _thumbnail: NSImage?
var thumbnail: NSImage? {
    if _thumbnail == nil {
        _thumbnail = generateThumbnail(from:inputURL,maxSize: 60)
    }
    return _thumbnail
}

当SwiftUI显示缩略图时,动态创建缩略图:

if let thumb = customImage.thumbnail {
    Image(nsImage: thumb)
        .resizable()
        .frame(width: 60, height: 60)
}

当创建属性含有图片的对象时,不会因为图片导致内存过大,只在需要显示图片时,才会加载。

   

如果您认为这篇文章给您带来了帮助,您可以在此通过支付宝或者微信打赏网站开发者。

欢迎加入我们的 微信交流群QQ交流群,交流更多精彩内容!
微信交流群二维码 QQ交流群二维码

发表回复

您的电子邮箱地址不会被公开。 必填项已用 * 标注