Why is my CGImage 3 x the size of the UIImage

2020-04-18 07:54发布

问题:

I have a function that takes a UIImage and a colour and uses it to return a UIImage in just that colour.

As part of the function the UIImage is converted to a CGImage but for some reason the CGImage is 3 times the size of the UIImage which means that the final result is 3 times the size that it should be.

Here is the function

func coloredImageNamed(name: String, color: UIColor) -> UIImage {

    let startImage: UIImage = UIImage(named: name)!
    print("UIImage W: \(startImage.size.width) H\(startImage.size.height)")

    let maskImage: CGImage = startImage.CGImage!
    print("CGImage W: \(CGImageGetWidth(maskImage)) H\(CGImageGetHeight(maskImage))")

    // Make the image that the mask is applied to (Just a rectangle of the color want to use)
    let colorImageSize: CGSize = CGSizeMake(startImage.size.width, startImage.size.height)
    let colorFillImage: CGImage = getImageWithColor(color, size: colorImageSize).CGImage!

    // Make the mask image into a mask
    let mask: CGImage = CGImageMaskCreate(CGImageGetWidth(maskImage),
        CGImageGetHeight(maskImage),
        CGImageGetBitsPerComponent(maskImage),
        CGImageGetBitsPerPixel(maskImage),
        CGImageGetBytesPerRow(maskImage),
        CGImageGetDataProvider(maskImage), nil, false)!

        // Create the new image and convert back to UIImage, then return
        let masked: CGImage! = CGImageCreateWithMask(colorFillImage, mask);
        let returnImage: UIImage! = UIImage(CGImage: masked)
     return returnImage
}

You can see in the first few lines I have used print() to print the size of each the UIImage and CGImage to the console. The CGImage is always 3 times the size of the UIImage... I suspect it has something to do with @2x, @3x etc?

So the question is why is this happening and what can do to get an Image out that is the same size as the one I start with?

回答1:

It's because UIImage has a scale property. This mediates between pixels and points. So, for example, a UIImage created from a 180x180 pixel image, but with a scale of 3, is automatically treated as having size 60x60 points. It will report its size as 60x60, and will also look good on a 3x resolution screen where 3 pixels correspond to 1 point. And, as you rightly guess, the @3x suffix, or the corresponding location in the asset catalog, tells the system to give the UIImage a scale of 3 as it forms it.

But a CGImage does not have such a property; it's just a bitmap, the actual pixels of the image. So a CGImage formed from a UIImage created from 180x180 pixel image is 180x180 points as well.