You need to enable JavaScript to run this app.
优惠活动
大模型
产品
解决方案
定价
更多

如何使用SDWebImage调整缓存图片大小及预处理云端图片?

解决方案

核心思路

要实现缓存图片更新为新尺寸、云端图片先调整再存缓存,关键在于自定义缓存KEY(结合目标尺寸区分不同版本的缓存),同时配合图片转换逻辑。


1. 更新已有缓存的图片为新尺寸

步骤:

  • 从SDImageCache中通过原URL的KEY取出旧图片
  • 调整图片到目标尺寸
  • 用原KEY替换缓存(或用新KEY保留原尺寸缓存)

代码示例:

// 目标尺寸,根据需求修改
let targetSize = CGSize(width: 200, height: 200)
// 原图片的URL
guard let originalURL = NSURL.sd_URL(with: ref) as URL? else { return }
let originalCacheKey = originalURL.absoluteString

// 1. 从缓存获取原图片
SDImageCache.shared.queryImage(forKey: originalCacheKey) { [weak self] originalImage, _, _ in
    guard let image = originalImage else { 
        print("原图片不在缓存中")
        return 
    }
    
    // 2. 使用SDWebImage的转换器调整尺寸(或自定义缩放方法)
    let resizingTransformer = SDImageResizingTransformer(size: targetSize, scaleMode: .aspectFill)
    guard let resizedImage = resizingTransformer.transform(image, for: originalURL) else { return }
    
    // 3. 更新缓存:二选一
    // 选项A:替换原缓存的图片(原尺寸图片会被覆盖)
    SDImageCache.shared.store(resizedImage, forKey: originalCacheKey, completion: {
        print("缓存已更新为新尺寸")
    })
    
    // 选项B:用新KEY存储(保留原尺寸缓存,新尺寸存为独立条目)
    // let newCacheKey = "\(originalCacheKey)_\(targetSize.width)x\(targetSize.height)"
    // SDImageCache.shared.store(resizedImage, forKey: newCacheKey, completion: nil)
}

2. 加载云端图片时先调整尺寸再存缓存

步骤:

  • 自定义缓存KEY(结合尺寸),确保转换后的图片存入对应KEY
  • 使用SDImageResizingTransformer在下载后自动调整尺寸
  • 让SDWebImage自动存储转换后的图片(或手动存储)

代码示例:

方式一:自定义缓存KEY过滤器(推荐)

通过自定义SDImageCacheKeyFilter,自动根据目标尺寸生成唯一缓存KEY:

// 自定义KEY过滤器,根据URL+尺寸生成缓存KEY
class SizeAwareCacheKeyFilter: SDImageCacheKeyFilter {
    func cacheKey(for url: URL, context: [SDWebImageContextOption : Any]?) -> String? {
        guard let targetSize = context?[.customTargetSize] as? CGSize else {
            return url.absoluteString
        }
        // 拼接尺寸信息到KEY中
        let sizeSuffix = String(format: "%.0fx%.0f", targetSize.width, targetSize.height)
        return "\(url.absoluteString)_\(sizeSuffix)"
    }
}

// 使用时:
let targetSize = CGSize(width: 200, height: 200)
// 配置全局缓存的KEY过滤器
SDImageCache.shared.cacheKeyFilter = SizeAwareCacheKeyFilter()

// 初始化图片管理器
let manager = SDWebImageManager(cache: SDImageCache.shared, loader: StorageImageLoader.shared)
// 创建尺寸转换器
let resizingTransformer = SDImageResizingTransformer(size: targetSize, scaleMode: .aspectFill)

// 加载图片
manager.loadImage(with: NSURL.sd_URL(with: ref) as URL?,
                  options: [.transformDownloadedImage], // 开启下载后自动转换
                  context: [
                      .imageTransformer: resizingTransformer,
                      .customTargetSize: targetSize // 传递尺寸给KEY过滤器
                  ],
                  progress: nil) { image, _, error, _, _, _ in
    if let resizedImage = image {
        print("图片已调整尺寸并自动存入缓存")
    }
}

方式二:手动存储转换后的图片

如果不想全局修改缓存KEY过滤器,可以手动生成KEY并存储:

let targetSize = CGSize(width: 200, height: 200)
guard let url = NSURL.sd_URL(with: ref) as URL? else { return }
// 生成带尺寸的缓存KEY
let customCacheKey = "\(url.absoluteString)_\(targetSize.width)x\(targetSize.height)"

let manager = SDWebImageManager(cache: SDImageCache.shared, loader: StorageImageLoader.shared)
let resizingTransformer = SDImageResizingTransformer(size: targetSize, scaleMode: .aspectFill)

manager.loadImage(with: url,
                  options: [],
                  context: [.imageTransformer: resizingTransformer],
                  progress: nil) { [weak self] image, _, error, _, _, _ in
    guard let resizedImage = image else { return }
    // 手动存入自定义KEY的缓存
    SDImageCache.shared.store(resizedImage, forKey: customCacheKey, completion: {
        print("调整后的图片已存入缓存")
    })
}

关于缓存KEY的说明

之前Stack Overflow方案失效的核心原因是没有用尺寸区分缓存KEY:

  • SDWebImage默认用URL的绝对字符串作为缓存KEY,不同尺寸的图片如果用同一个KEY,会导致缓存覆盖或读取错误
  • 必须在KEY中加入尺寸标识(如200x200),让不同尺寸的图片拥有独立的缓存条目,这样才能正确更新和读取对应尺寸的缓存

内容的提问来源于stack exchange,提问作者Icare

相关产品推荐
方舟 Agent Plan

超全模态模型 × Harness 升级,最新支持 Deepseek-V4.1-Flash、GLM-5.3 系列、Doubao-Seedream-5.0-pro、Kimi-K3 (部分), 限时 9.9 元起

最近更新时间:2026.08.13 12:10:56