在 UIImage 上绘制另一个图像 -

Posted

技术标签:

【中文标题】在 UIImage 上绘制另一个图像 -【英文标题】:Draw another image on a UIImage - 【发布时间】:2018-06-10 15:10:21 【问题描述】:

我正在尝试实现在 UIImageView 的特定点绘制图像的功能。

1.) 所以用户拍了一张照片 2.) 照片在“Aspect Fit”的 UIImageView 中显示给用户 3.) 用户点击 UIImageView 将图像放在点击点 4.) 显示组合图像

代码:

extension UIImage 
func image(byDrawingImage image: UIImage, inRect rect: CGRect) -> UIImage! 
    UIGraphicsBeginImageContextWithOptions(size, false, 0)
    draw(in: CGRect(x: 0, y: 0, width: size.width, height: size.height))
    image.draw(in: rect)
    let result = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return result

source

    @IBAction func imageTapped(_ sender: UITapGestureRecognizer) 


    let pointTapped = sender.location(in: imageDIsplay)

    imageDIsplay.image = originalImage?.image(byDrawingImage: #imageLiteral(resourceName: "checkmark.png"), inRect: CGRect(x: originalImage!.size.width / imageDIsplay.frame.width * pointTapped.x, y: originalImage!.size.height / imageDIsplay.frame.height * pointTapped.y, width: 100, height: 100))


我的问题:“复选标记图像”永远不在我点击的确切位置。

我尝试了很多而不是originalImage!.size.width / imageDIsplay.frame.width 以获得更好的比率,包括CGRect AVMakeRectWithAspectRatioInsideRect(CGSize aspectRatio, CGRect boundingRect);。但没有任何工作正常。

我错过了什么?

谢谢! 莎拉

【问题讨论】:

" 照片在“Aspect Fit”中的 UIImageView 中显示给用户“这就是问题所在。用户点击在图像视图中的点与用户点击在图像中的点不同,因为图像视图正在改变大小/位置图像以显示它。您需要计算回图像坐标才能知道在哪里放置复选标记。 “我尝试了很多” 好的,所以您似乎确实意识到这就是问题所在。但是你没有展示你尝试了什么,所以不可能说你做错了什么。 还有一件事:即使你解决了这个问题,你也需要决定在哪里绘制与点击点相关的复选标记图像。你想要它的左上角在点击点吗?或者它的 center 在点击点?在我看来,用户自然会期待后者。 图片应该在与点击点相关的中心。是的,我意识到这就是问题所在。 “我尝试了很多”我是说我尝试了很多关系来获得正确的比例,比如 let actualSize = AVMakeRect(aspectRatio: (originalImage?.size)!, insideRect: imageDIsplay.frame).size.height let imageSize = originalImage!.size.height 让比率 = imageSize / actualSize。但我不确定我是否走在正确的道路上...... 【参考方案1】:

您绝对是在正确的轨道上。当图像以“宽高比匹配”内容模式显示时,手头有一个有效的utility 用于将图像视图边界中的一个点转换为图像边界中的一个点:

extension UIImageView 
    func convertPointToImageCoordinates(_ p:CGPoint) -> CGPoint 
        switch self.contentMode 
        case .scaleAspectFit:
            let r = AVMakeRect(
                 aspectRatio: self.image!.size, insideRect: self.bounds)
            let scale = self.image!.size.width / r.width
            var p2 = CGPoint(x: p.x - r.minX, y: p.y - r.minY)
            p2 = CGPoint(x: p2.x * scale, y: p2.y * scale)
            return p2
        default:
            fatalError("not written")
        
    

现在您可以获得相对于原始图像的点击坐标,因此您可以决定将复选标记图像放置在哪里。

【讨论】:

UIImageView 没有设置变换矩阵吗? @DavidBerry 变换矩阵是什么? UIImage 不是视图,因此它没有变换。如果它改变了它的自己的 变换,视图会它自己 被扭曲。它只是根据内容模式绘制图像,就像任何视图绘制一样。 但是UIImageView (显然)是一个视图并且确实有一个变换矩阵。我假设它使用该矩阵来正确缩放和绘制图像。当然我们都知道这意味着什么 :) 并没有真正看过它,只是想如果我正在编写视图我会怎么做。 @DavidBerry 我更喜欢了解它的实际工作原理。 @DavidBerry 我对你的解决方案很好奇@matt 非常感谢你的回复,至少我接近了它就像一个魅力:-D 当然我投票给你的答案 - 如果你会看到它我有足够的声誉:)

以上是关于在 UIImage 上绘制另一个图像 -的主要内容,如果未能解决你的问题,请参考以下文章

用比例绘制 UIImage 并平移

在 UIImage 上绘制文本

在 UIImage 上使用 Core Graphic 绘制渐变结果不一致

创建特定大小的 UIImage

将 NSString 绘制到 UIImage

使用 Core Graphics 绘制 UIImage?