ios - 来自肖像 UIImage 的 CGImage

标签 ios swift uiimage cgimage

试图弄清楚当一个人得到 cgImage 时图像是如何旋转或翻转的来自 UIImage这是在肖像模式。

即如果我有案例,image.size.width < image.size.height然后调用let cg = image.cgImage! , 我得到 cg.width > cg.height (实际上,cg.width == image.size.height && cg.height == image.size.width)。我知道 CGImage 的坐标差异和 UIImage , 但我不明白 - UIImage 的哪个角落被视为 CGImage 的来源图像是否以某种方式翻转?

这弄乱了我的裁剪代码,我在其中简单地计算了 UIImage 的裁剪矩形。但随后尝试通过调用 image.cgImage!.cropping(to: rect) 来裁剪图像给了我意想不到的结果(裁剪了错误的区域)。是否rect需要在 CGImage的坐标系?我试着像这样翻转它,但它也无济于事:

swap(&croppingRect.origin.x, &croppingRect.origin.y)
swap(&croppingRect.size.width, &croppingRect.size.height)

最佳答案

对于那些可能遇到与我类似问题的人,我发布了这个 Swift playground 代码,它帮助我了解发生了什么以及如何解决它:

import UIKit

let image : UIImage = UIImage(named: "down.JPG")!
image.size
image.imageOrientation.rawValue

let center = CGPoint(x: 0.3, y: 0.3)
let kx = (center.x > 0.5 ? (1-center.x) : center.x)
let ky = (center.y > 0.5 ? (1-center.y) : center.y)
let size = CGSize(width: image.size.width*kx, height: image.size.height*ky)
// cropRect is defined in UIImage coordinate system
// it is defined as a rectangle with center in "center", with proportions
// to the original image. size of rectangle is defined by the distance from 
// the center to the nearest edge divided by 2
// this was chosen due to my specific needs and can be adjusted at will 
// (just don't exceed limits of the original image)
var cropRect = CGRect(x: center.x*image.size.width-size.width/2,
                      y: center.y*image.size.height-size.height/2,
                      width: size.width,
                      height: size.height)

cropRect

if self.imageOrientation == .right || self.imageOrientation == .down || self.imageOrientation == .left
{
    let k : CGFloat = (self.imageOrientation == .right ? -1 :(self.imageOrientation == .left ? 1 : 2))
    let dy = (self.imageOrientation == .right ? self.size.width : (self.imageOrientation == .left ? 0 :self.size.height))
    let dx = (self.imageOrientation == .down ? self.size.width : (self.imageOrientation == .left ? self.size.height : 0))
    let rotate = CGAffineTransform(rotationAngle: k*90/180*CGFloat.pi)
    let translate = CGAffineTransform(translationX: dx, y: dy)
    cropRect = cropRect.applying(rotate).applying(translate)
}

let cgImage = image.cgImage!
cgImage.width
cgImage.height

cropRect

let cropped = cgImage.cropping(to: cropRect)

if cropped != nil
{
    cropped!.width
    cropped!.height

    let croppedImage = UIImage(cgImage: cropped!, scale: image.scale, orientation: image.imageOrientation)

}

为所有可能的相机配置拍摄 4 张图片:“up.JPG”、“down.JPG”、“left.JPG”和“right.JPG”,并将它们上传到 Resources 的子文件夹你的 Playground 。一个一个地加载它们并检查参数发生了什么。此代码帮助我提出了可行的解决方案:当图像具有 .right.down 方向时,将仿射变换应用于裁剪矩形以获得所需的裁剪

关于ios - 来自肖像 UIImage 的 CGImage,我们在Stack Overflow上找到一个类似的问题: https://stackoverflow.com/questions/43712847/

相关文章:

ios - UInavigationController 中使用异步代码的弱无主用法

multithreading - NSSplitViewItem 折叠动画和窗口 setFrame 冲突

swift - 我有字典数组类型的 JSON 数据。如何使用 Codable 协议(protocol)对其进行解码?

ios - 如何在特定框架中在iOS上显示GIF,直到完全加载才显示它并允许缩放?

ios - 检测带有圆角的卡片边缘

ios - 视网膜屏幕的ios逻辑

ios - cloudkit 错误没有收到 Assets 的 authToken

ios - 如何让应用程序在后台播放音频(iOS 上的 phonegap 1.5.0)

macos - Swift _ABSearchComparison 不可转换为 ABSearchComparison

ios - 电子邮件镇静 iOS 8