简体   繁体   English

使用 UIScreen.main.scale 以编程方式缩放 @3x 图像的结果与资产目录不同

[英]Programmatic scaling of @3x image with UIScreen.main.scale has different result than Asset Catalog

I have an image being returned from the backend at an @3x scale.我有一个以@3x比例从后端返回的图像。 I am looking to scale the image programmatically based on the device.我希望根据设备以编程方式缩放图像。 Something like:就像是:

let imageSize = CGSize(width: 300, height: 150)
let scale = UIScreen.main.scale / 3.0
let scaledSize = imageSize.applying(CGAffineTransform(scaleX: scale, y: scale))

As an example, on the iPhone 6s simulator, UIScreen.main.scale would be 2.0 ;例如,在 iPhone 6s 模拟器上, UIScreen.main.scale将为2.0 thus the resulting scaledSize would be (2.0 / 3.0) * (width: 300, height: 150) = (width: 200, height: 100)因此生成的scaledSize将是(2.0 / 3.0) * (width: 300, height: 150) = (width: 200, height: 100)

However, the image comes out too large.但是,图像太大。

I tried adding the same @3x asset to the Asset Catalog and using it directly in code, to find the size returned is @1x (which looks right).我尝试将相同的@3x资产添加到资产目录并直接在代码中使用它,以找到返回的大小为@1x (看起来正确)。 So, in this case, using the Asset Catalog returns an image of size (width: 100, height: 50)因此,在这种情况下,使用 Asset Catalog 会返回大小为(width: 100, height: 50)的图像

Am I missing something about how UIScreen.main.scale could be used for this purpose?我是否缺少有关如何UIScreen.main.scale用于此目的的信息? What would be the correct way to scale the @3x image programmatically?以编程方式缩放@3x图像的正确方法是什么?

It really depends on why you want to scale your image.这实际上取决于您为什么要缩放图像。

If you are displaying the image in a UIImageView , it will be scaled automatically by UIKit, so there's really no need to manually scale it.如果您在UIImageView中显示图像,它将由 UIKit 自动缩放,因此实际上不需要手动缩放它。

However, if you have some other purpose... maybe you want to save a scaled version on the device?但是,如果您有其他目的……也许您想在设备上保存缩放版本? maybe you're doing something else with it?也许你正在用它做其他事情?

One approach is to use UIGraphicsImageRenderer - for example:一种方法是使用UIGraphicsImageRenderer - 例如:

func resizedImage(from image: UIImage, to scale: CGFloat) -> UIImage? {
    if scale == 1.0 {
        // don't need to scale the image,
        //  so just return it
        return image
    }
    let newSize = CGSize(width: image.size.width * scale, height: image.size.height * scale)
    let renderer = UIGraphicsImageRenderer(size: newSize)
    return renderer.image { (context) in
        image.draw(in: CGRect(origin: .zero, size: newSize))
    }
}

You could then scale your image like this:然后,您可以像这样缩放图像:

    // using a 300x150 image for demonstration
    guard let img = UIImage(named: "bkg300x150") else {
        fatalError("Could not load image!!!!")
    }
    
    let scale = UIScreen.main.scale / 3.0

    guard let scaledImage = resizedImage(from: img, to: scale) else {
        fatalError("Image resize failed???")
    }
    
    print("Orig:", img.size)
    print("Scaled:", scaledImage.size)

the output on an iPhone 8 - @2x screen scale: iPhone 8 上的 output - @2x 屏幕比例:

Orig: (300.0, 150.0)
Scaled: (200.0, 100.0)

the output on an iPhone 13 Pro Max - @3x screen scale: iPhone 13 Pro Max 上的 output - @3x 屏幕比例:

Orig: (300.0, 150.0)
Scaled: (300.0, 150.0)

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM