为什么从FileManager数据初始化的UIImages具有错误的比例?

时间:2017-05-14 01:16:21

标签: ios swift swift3 uiimage alamofire

我使用Alamofire从我写的请求脚本下载图像。然后我将图像保存到设备中,然后使用以下功能调用它:

    private static func save(image: UIImage, fileName: String) -> String? {
        let fileURL = documentsUrl.appendingPathComponent(fileName)
        if let imageData = UIImageJPEGRepresentation(image, 1.0) {
            do{
                try imageData.write(to: fileURL) // When the images are downloaded, they seem to have the correct scale set already. Maybe we should verify this
                if image.scale != UIScreen.main.scale {
                    print("save - image scale: \(image.scale) does not match device scale: \(UIScreen.main.scale)")
                }
                print("Saving image to file: \(fileURL)")
                return fileName // ----> Save fileName
            }
            catch{
                print("Error info: \(error)")
            }
        }
        print("Error saving image")
        return nil
    }


    private static func loadImage(_ fileName: String) -> UIImage? {
        let fileURL = documentsUrl.appendingPathComponent(fileName)
        print("Loading image from file: \(fileURL)")
        do {
            let imageData = try Data(contentsOf: fileURL)
            //let image = UIImage(data: imageData) // Bad - the image will appear twice as big as it should be, and very blurry!
            let image = UIImage(data: imageData, scale: UIScreen.main.scale) // Alamofire extension...important. Make sure that images we downloaded are recalled with the right scale for our device
            return image
        } catch {
            print("Error loading image : \(error)")
        }
        return nil
    }

如果我下载200x200像素图像,iOS会将其识别为iPhone 7模拟器中刻度为2.0的100x100点图像。如果我保存该图像并在不设置Alamofire提供的UIImage初始化程序扩展中设置比例的情况下调用它,iOS会将其视为200x200点图像,比例为1.0。

为什么会这样?这是以正确的比例和分辨率保存和加载图像的最佳做法吗?

2 个答案:

答案 0 :(得分:0)

如果使用UIImage.init(contentsOfFile:)或其他类似方法,则取决于png资源的文件名,屏幕比例和该目录中的其他图像。

我使用以下图片进行了快速测试。所有图像只是不同的文件名。图像分辨率为200x200。用iPhone 7测试。

图像文件夹

├─ Images
  ├─ image1.png
  ├─ image2@2x.png
  ├─ image3.png
  ├─ image3@2x.png

代码

let imagesDirectory = .... // Images directory 

if let image1 = UIImage.init(contentsOfFile: imagesDirectory + "image1.png") {
    print("image1 scale: \(image1.scale)")
}

if let image2 = UIImage.init(contentsOfFile: imagesDirectory + "image2.png") {
    print("image2 scale: \(image2.scale)")
}

if let image22x = UIImage.init(contentsOfFile: imagesDirectory + "image2@2x.png") {
    print("image2@2x scale: \(image22x.scale)")
}

if let image3 = UIImage.init(contentsOfFile: imagesDirectory + "image3.png") {
    print("image3 scale: \(image3.scale)")
}

输出

image1 scale: 1.0
image2 scale: 2.0
image2@2x scale: 2.0
image3 scale: 2.0

您可以看到相同图像的输出,但文件名不同:)

结论

使用适当的后缀保存图像,如@ 2x和@ 3x。

答案 1 :(得分:0)

从文件加载图像时,您必须告诉正确的比例因子。仅当从捆绑/资产目录系统加载时才能识别出图像比例因子。

这就是代码行:

let image = UIImage(data: imageData, scale: 1.0)

您可以将图像比例解释为与设备的比例相同。在iPhone 7中它是2.0。在iPhone 7 Plus上它将是3.0。从文件加载图像时,不应按设备比例缩放。相反,你必须明确告诉它。 请改用:

{{1}}