Изображение занимает больше места в кэше, чем его первоначальный размер в tvos

Ясно, почему мое изображение занимает больше размера в кэш-памяти, чем исходный размер. Я использую библиотеку alamofireImage для этой цели, и мое приложение для tvOS. Вот мой код

let photoCache = AutoPurgingImageCache(
        memoryCapacity: 100 * 1024 * 1024,
        preferredMemoryUsageAfterPurge: 60 * 1024 * 1024
    )


Alamofire.request(.GET, request, headers: headers)
            .responseJSON { response in

                if let JSON = response.result.value {
                    self.imagesArray = JSON["results"] as! NSMutableArray
                    for result in self.imagesArray{

                        self.getNetworkImage(result["url"] as! String, completion: { (UIImage) in

                        })}}}



func getNetworkImage(urlString: String, completion: (UIImage -> Void)) -> (Request) {
        return Alamofire.request(.GET, urlString, headers: headers).responseImage { (response) -> Void in
            guard let image = response.result.value else { return }
            completion(image)
            if response.response?.statusCode == 200{
                self.cacheImage(image, urlString: urlString)
                self.cachedImagesOnly.addObject(urlString)
            }
            if self.counter == 4{
               self.activityIndicatorView.stopAnimating()
               self.activityIndicatorView.hidden = true

                var downloadedImage = UIImage()
                let dicr = self.cachedImagesOnly.firstObject
                 let urlStringFetch = dicr!["url"] as! String
                print("Fetching url: \(urlStringFetch)")

                downloadedImage = self.cachedImage(urlStringFetch)!
                print("Size of image from cache: \(downloadedImage.size)")
                self.ssImage.image = downloadedImage

                })

            }

        }
    }

func cacheImage(image: Image, urlString: String) {

        print("Total Cache memory size: \(self.photoCache.memoryCapacity)")
        self.counter += 1
        let jpgImageData = UIImageJPEGRepresentation(image, 1.0)
        print("Image size before cache : \(jpgImageData?.length)")
        self.cachedImagesOnly.addObject(urlString)
        let URLRequest = NSURLRequest(URL: NSURL(string: "\(urlString)")!)
        self.photoCache.addImage(UIImage(data: jpgImageData!)!, forRequest: URLRequest)
        print("Cache memory usage after image cache: \(self.photoCache.memoryUsage)")

    }

Журнал результатов:

Total Cache memory size: 104857600
Image size: (1752.0, 1896.0) and string as identifier: http://image.com/9493.jpg
Image size before cache : Optional(1738247)
Cache memory usage after image cache: 13287168
Total Cache memory size: 104857600
Image size: (2875.0, 3872.0) and string as identifier: http://image.com/5025.jpg
Image size before cache : Optional(7049508)
Cache memory usage after image cache: 57815168
Total Cache memory size: 104857600
Image size: (2394.0, 3866.0) and string as identifier: http://image.com/169215.jpg
Image size before cache : Optional(6049349)
Cache memory usage after image cache: 94835984
Total Cache memory size: 104857600
Image size: (3811.0, 3049.0) and string as identifier: http://image.com/786.jpg
Image size before cache : Optional(2848557)
Cache memory usage after image cache: 46478956

Итак, я прочитал на GitHub, что они используют FIFO, когда кэш-память заполнена, поэтому, кроме простого удаления первого объекта, он удаляет два или три согласно расчету. Кроме того, просто рассмотрим первый результат регистрации, размер изображения составляет 1738247, и IDK добавляет к этому дополнительные издержки, которые после кэширования увеличивают размер использования до 13287168, что почти в 13 раз более странно. Если кто-то прошел через эту проблему или может определить мою ошибку, будет высоко оценен. Заранее спасибо.

1 ответ

Это немного сложно, потому что здесь много движущихся частей:

  • Во-первых, когда вы получаете изображение из веб-службы, есть оригинальный ресурс, NSData, В вашем фрагменте кода я не думаю, что вы когда-либо видели этот оригинальный ресурс, потому что вы позволяете Alamofire преобразовать его в UIImage (см. следующий пункт), прежде чем он будет доставлен вам. Но если вы смотрели это в веб-браузере (или каком-либо инструменте, таком как Charles или WireShark), это размер исходного актива.

  • Затем вы конвертируете это в UIImage, который, если исходный актив был сжат, может оставаться сжатым до тех пор, пока вы не используете его в UIImageView или т.п.

    Как только вы используете это UIImage, он несжатый, обычно занимает гораздо больше памяти, обычно четыре байта на пиксель (один байт для красного, зеленого, синего и альфа-каналов соответственно, хотя есть и другие форматы).

  • Когда вы позже позвоните UIImageJPEGRepresentationВы сейчас строите новый NSData от UIImage, Люди часто ошибочно думают, что это то же самое, что и первоначальный актив, но это не так. Если вы используете качество сжатия 1,0, это часто намного больше, чем исходный ресурс (хотя, вероятно, меньше, чем несжатый) UIImage.) И если вы используете более низкое качество сжатия, размер часто более приемлем, но вы вводите некоторые артефакты JPEG из-за его сжатия с потерями. (Сжатие PNG без потерь, хотя обычно получающиеся активы больше.)

Итак, длинный и короткий, что вы сравниваете NSData представления (в частности, JPEG с compressionQuality 1) к объему памяти, занятой UIImage который кешируется, и я бы не ожидал, что эти цифры совпадут. Это очень разные вещи.

Другие вопросы по тегам