Skip to content
New issue

Have a question about this project? Sign up for a free GitHub account to open an issue and contact its maintainers and the community.

By clicking “Sign up for GitHub”, you agree to our terms of service and privacy statement. We’ll occasionally send you account related emails.

Already on GitHub? Sign in to your account

使用ResizingImageProcessor Crash #2268

Open
intsig171 opened this issue Jul 4, 2024 · 7 comments
Open

使用ResizingImageProcessor Crash #2268

intsig171 opened this issue Jul 4, 2024 · 7 comments

Comments

@intsig171
Copy link

    let thumbnailProcessor = ResizingImageProcessor(referenceSize: CGSize(width: maxLength, height: maxLength), mode: .aspectFit)
    
    wrappedValue.kf.setImage(
        with: URL(string: urlString),
        placeholder: placeholder,
        options: [
            .processor(thumbnailProcessor),
            .scaleFactor(UIScreen.main.scale),
            .cacheOriginalImage
        ])

在列表中加载图片,崩溃在此。

image

@meiyongsheng
Copy link

你这是内存爆了, 如果是大图片的话不建议使用,业界的标准做法一般都是 区域解码

或者这里可以使用

guard let imageSource =  CGImageSourceCreateWithURL(URL, nil) else {
        return nil
    }
    
    let maxDimensionInPixels = max(pointSize.width, pointSize.height) * scale
    let downsampleOptions = [
        kCGImageSourceCreateThumbnailFromImageAlways: true,
        kCGImageSourceShouldCacheImmediately: true,
        kCGImageSourceCreateThumbnailWithTransform: true,
        kCGImageSourceThumbnailMaxPixelSize: maxDimensionInPixels] as CFDictionary
    guard let downsampledImage = CGImageSourceCreateThumbnailAtIndex(imageSource, 0, downsampleOptions) else {
        return nil
    }

的方式降采样一下 , pointSize 为你将来要降采样到的大小, 这里注意 一定不能先把URL读取出来为data在处理,

可以尝试一下 方式一, 如果还有问题建议采用区域解码

@intsig171
Copy link
Author

我的诉求也挺简单,setImage(with: URL(string: urlString), placeholder: placeholder) 大部分场景下是够用的。 但是有一些异常网络图片(宽高非常大,比如: 16000*17000),导致内存爆掉。 所以我就想做一下兼容处理,如果原始图片尺寸太大的话,就resize一下。 有两个要求: 1. 不能改变图片的原始比例(未下载时尺寸是未知的)。2. 要兼顾在列表中,不要因为异步的问题导致图片错乱。

@meiyongsheng
Copy link

建议还是从业务上区分一下, 最起码过滤绝大多数的场景,在集中处理小case事件,针对于超大图,目前比较常见只能是降采样或者区域解码了,不然内存消耗太大的时候容易FOOM

@intsig171
Copy link
Author

很难从业务中区分,异常的大图可能出现在任意地方(数据质量不好)。但是给setImage设置Options又会引起内存的问题。

@meiyongsheng
Copy link

因为KF内部的降采样也是先通过能到Data 在进行降采样的
image
你可以尝试在你本地的库中修改一下: 改为传URL进来降采样 看看效果怎样, 并且kCGImageSourceThumbnailMaxPixelSize 是一个上限值, 你根据实际的上限传一下 约束范围(避免影响正常的小图)

@make1a
Copy link

make1a commented Aug 19, 2024

我有个疑问,KF 内部 做下采样的时候 是 DownsamplingImageProcessor 把 data 传到 public static func downsampledImage(data: Data, to pointSize: CGSize, scale: CGFloat) -> KFCrossPlatformImage? 方法内实现的。 这里为什么没有使用WWDC 也推荐的 let imageSource = CGImageSourceCreateWithURL(URL, nil) 方案 来优化内存呢?

@meiyongsheng
Copy link

目前我们自己的工程里面都是使用 let imageSource = CGImageSourceCreateWithURL(URL, nil) 的方式来进行降采样,因为这个不用读取全部的data,比较节省空间和时间, 但是kf中处理图片在决定是是那个provider 的时候 已经通过 file来读取data,然后再传入作为后续图片的操作,改为CGImageSourceCreateWithURL 你需要看 好不好处理

Sign up for free to join this conversation on GitHub. Already have an account? Sign in to comment
Labels
None yet
Projects
None yet
Development

No branches or pull requests

3 participants