使用UIGraphicImageRenderer的CGContext重绘图像,翻转图像.如何防止翻转? [英] Using CGContext of UIGraphicImageRenderer to redraw an image, flipped the image. How to prevent the flip?

查看:93
本文介绍了使用UIGraphicImageRenderer的CGContext重绘图像,翻转图像.如何防止翻转?的处理方法,对大家解决问题具有一定的参考价值,需要的朋友们下面随着小编来一起学习吧!

问题描述

给出一个图像,当我想转换为标准的sRGB时,我可以使用CGContext来帮助绘制它,如下所示.

Given an image, when I want to convert to standard sRGB, I can CGContext to help draw it as below.

给出原始图像

当我直接使用 CGContext 时,它会正确重绘

When I use the CGContext directly, it redraws correctly

extension UIImage {
    func toSRGB() -> UIImage {        
        guard let cgImage = cgImage,
            let colorSpace = CGColorSpace(name: CGColorSpace.sRGB),
            let cgContext = CGContext(
                data: nil,
                width: Int(size.width),
                height: Int(size.height),
                bitsPerComponent: 8,
                bytesPerRow: 0,
                space: colorSpace,
                bitmapInfo: CGImageAlphaInfo.premultipliedLast.rawValue)
            else { return self }
        cgContext.draw(cgImage, in: CGRect(origin: .zero, size: size))

        guard let newCGImage = cgContext.makeImage()
            else { return self }

        return UIImage.init(cgImage: newCGImage)
    }
}

但是,如果我使用 UIGraphicImageRenderer

extension UIImage {
    func toSRGB() -> UIImage {
        guard let cgImage = cgImage else { return self }

        let renderer = UIGraphicsImageRenderer(size: size)
        return renderer.image { ctx in
            ctx.cgContext.draw(cgImage, in: CGRect(origin: .zero, size: size))
        }
    }
}

图像被上下颠倒,如下所示.为什么会发生翻转,如何避免翻转?

The image got flipped upside down as below. Why did it get flipped, and how can I avoid the flip?

推荐答案

无需获取cgImage.您可以简单地绘制UIImage:

No need to get the cgImage. you can simply draw the UIImage:

extension UIImage {
    func toSRGB() -> UIImage {
        UIGraphicsImageRenderer(size: size).image { _ in
            draw(in: CGRect(origin: .zero, size: size))
        }
    }
}

图像被翻转的原因是之间的差异UIKit和Quartz中的坐标系统.UIKit垂直原点位于顶部,而Quartz垂直原点位于底部.解决此问题的最简单方法是应用CGAffineTransform将其缩放为负一,然后向后平移高度距离:

The reason why your image got flipped is the difference between coordinate system in UIKit and Quartz. UIKit vertical origin is at the top while Quartz vertical origin is at the bottom. The easiest way to fix this is to apply a CGAffineTransform scaling it by minus one and then translating the height distance backwards:

extension CGAffineTransform {
    static func flippingVerticaly(_ height: CGFloat) -> CGAffineTransform {
        var transform = CGAffineTransform(scaleX: 1, y: -1)
        transform = transform.translatedBy(x: 0, y: -height)
        return transform
    }
}


extension UIImage {
    func toSRGB() -> UIImage {
        guard let cgImage = cgImage else { return self }
        return UIGraphicsImageRenderer(size: size).image { ctx in
            ctx.cgContext.concatenate(.flippingVerticaly(size.height))
            ctx.cgContext.draw(cgImage, in: CGRect(origin: .zero, size: size))
        }
    }
}

编辑/更新:

要保持比例为1倍,您可以传递图像渲染器格式:

To keep the scale at 1x you can pass an image renderer format:

extension UIImage {
    func toSRGB() -> UIImage {
        guard let cgImage = cgImage else { return self }
        let format = imageRendererFormat
        format.scale = 1
        return UIGraphicsImageRenderer(size: size, format: format).image { ctx in
            ctx.cgContext.concatenate(.flippingVerticaly(size.height))
            ctx.cgContext.draw(cgImage, in: CGRect(origin: .zero, size: size))
        }
    }
}

这篇关于使用UIGraphicImageRenderer的CGContext重绘图像,翻转图像.如何防止翻转?的文章就介绍到这了,希望我们推荐的答案对大家有所帮助,也希望大家多多支持IT屋!

查看全文
登录 关闭
扫码关注1秒登录
发送“验证码”获取 | 15天全站免登陆