Alamofire / AlamofireImage

AlamofireImage is an image component library for Alamofire
MIT License
3.98k stars 523 forks source link

Always downloading images in 2000, 1000 as max size #449

Closed PeHk closed 3 years ago

PeHk commented 3 years ago

What did you do?

I am using the basic ImageDownloader to download panorama images from my API.

What did you expect to happen?

My uploaded panorama images are in resolution 6000x3000 px so I expected to have UIImage with same resolution.

What happened instead?

Downloaded UIImages are in 2000x1000 px resolution instead

Alamofire Environment

Alamofire version: 5.4 Xcode version: 12.5.1 Swift version: 5.4.2 Platform(s) running AlamofireImage: macOS version running Xcode: 11.5.1 (20G80)

jshier commented 3 years ago

This is expected behavior, as AlamofireImage uses the device's screen scale when decoding images. A 6000x3000 image will be 2000x1000 on a 3x device, like a Pro Max. Depending on your usage you should be able to disable the behavior.

PeHk commented 3 years ago

This is expected behavior, as AlamofireImage uses the device's screen scale when decoding images. A 6000x3000 image will be 2000x1000 on a 3x device, like a Pro Max. Depending on your usage you should be able to disable the behavior.

How I can disable this? Or maybe better question, do I want to disable this? Since I am using alamofireImage for downloading panorama and then showing it to the user. In terms of quality, I think it's better to have higher resolution images, but I don't want to overkill it with high quality image with big size when we talking about iPhone and iPad screens.

jshier commented 3 years ago

Sorry, I should clarify. This setting simply sets the UIImage's scale property, it doesn't actually resize the image. You do need to be careful with very high res images, as the system can kill your app for using too much memory, or when the system is low on memory. The resolution you're seeing here is the "points" on the screen the UIImage will appear, not the resolution of the underlying image.

Disabling it depends on how you're using AlamofireImage to download the image. What does your usage look like? Usually it's just a parameter for the responseImage method.

PeHk commented 3 years ago

I was using this code:

let downloader = ImageDownloader()
let urlRequest = URLRequest(url: URL(string: "https://httpbin.org/image/jpeg")!)

downloader.download(urlRequest) { response in
    print(response.request)
    print(response.response)
    debugPrint(response.result)

    if case .success(let image) = response.result {
        print(image)
    }
}

So the downloader download the whole size image and then it rescale the image to the best scale for current device? Because I've recreated the original Alamofire request:

Future({ promise in
            AF.download(
                url,
                method: .get,
                encoding: JSONEncoding.default,
                headers: nil,
                to: self.destination)
                .downloadProgress(closure: { (progress) in
                    //progress closure
                })
                .responseData(completionHandler: { (response) in
                    switch response.result {
                    case .success(let value):
                        promise(.success(value))
                    case .failure(let error):
                        promise(.failure(self.createError(response: response.response, AFerror: error, AFIerror: nil, data: response.value)))
                    }
                })
        })

To get the wholesize image as UIImage... but to be honest I cannot really see the difference between... My point is just to have a good quality panorama but in efficient way.

jshier commented 3 years ago

No, as I said there is no resizing occurring. Instead, the UIImage simply has its scale set. From Apple's docs:

If you multiply the logical size of the image (stored in the size property) by the value in this property, you get the dimensions of the image in pixels.

There is no efficiency impact here, it only affects how the UIImage is show in displays. If you want the UIImage to be the original size, you can set the scale to 1. If you want to customize the scale of the images you download using ImageDownloader, you can pass an instance ImageResponseSerializer initialized with an imageScale of 1.

downloader.download(urlRequest, serializer: .init(imageScale: 1)) { response in
  // ...
}

I suggest you do some research into how to deal with large images on Apple's platforms. AlamofireImage can help you download, filter, and explicitly resize the images if you need but doesn't offer any help for efficiently displaying images. That's up to UIImage and how you display it. You may be better off downloading the full resolution images to disk and using CoreGraphics to produce thumbnails as the user views the image, but you'll want to evaluate solutions appropriate to your use.

By the way, Alamofire already includes a DownloadResponsePublisher, no need to wrap it in a Future manually.