如何确定用户在UIImage(非UIImageView)上的点击像素坐标?
获取UIImageView点击位置对应的UIImage真实像素坐标
当然可以实现!核心思路是把UIImageView上的点击坐标,结合图片的缩放模式和视图布局参数,转换为原始UIImage的真实像素坐标。下面给你一步步讲清楚怎么弄:
首先,你需要给UIImageView添加点击手势(或者在touchesBegan里处理),先拿到点击点在UIImageView中的坐标。然后关键是计算图片在视图里的缩放比例和偏移量——因为UIImageView的contentMode(比如Aspect Fit、Aspect Fill这些)会影响图片的显示位置和大小,这一步必须考虑到。最后把点击点转换到图片的坐标系,再结合图片的scale(处理@2x/@3x这类Retina图),就能得到真实的像素坐标了。
完整代码示例(Swift)
先给UIImageView添加点击手势:
// 假设你的UIImageView叫imageView let tapGesture = UITapGestureRecognizer(target: self, action: #selector(handleImageTap(_:))) imageView.addGestureRecognizer(tapGesture) imageView.isUserInteractionEnabled = true
然后写处理点击的方法:
@objc func handleImageTap(_ gesture: UITapGestureRecognizer) { guard let imageView = gesture.view as? UIImageView, let targetImage = imageView.image else { print("无法获取图片或视图") return } // 1. 获取点击点在UIImageView内的坐标 let tapLocation = gesture.location(in: imageView) // 2. 计算图片在视图中的缩放比例和偏移量 let imageSize = targetImage.size let viewBounds = imageView.bounds.size var scale: CGFloat = 1.0 var xOffset: CGFloat = 0.0 var yOffset: CGFloat = 0.0 switch imageView.contentMode { case .scaleAspectFit: // 按比例缩放,确保图片完整显示,居中 scale = min(viewBounds.width / imageSize.width, viewBounds.height / imageSize.height) xOffset = (viewBounds.width - imageSize.width * scale) / 2 yOffset = (viewBounds.height - imageSize.height * scale) / 2 case .scaleAspectFill: // 按比例缩放,填满视图,超出部分裁剪 scale = max(viewBounds.width / imageSize.width, viewBounds.height / imageSize.height) xOffset = (viewBounds.width - imageSize.width * scale) / 2 yOffset = (viewBounds.height - imageSize.height * scale) / 2 case .scaleToFill: // 拉伸图片填满整个视图 scale = max(viewBounds.width / imageSize.width, viewBounds.height / imageSize.height) xOffset = 0 yOffset = 0 case .center: // 图片不缩放,居中显示 xOffset = (viewBounds.width - imageSize.width) / 2 yOffset = (viewBounds.height - imageSize.height) / 2 // 其他contentMode(比如.top、.left等)可以类似计算偏移量,这里就不一一列举了 default: break } // 3. 将点击点转换为图片坐标系内的逻辑点坐标 let imageLogicX = (tapLocation.x - xOffset) / scale let imageLogicY = (tapLocation.y - yOffset) / scale // 检查点击点是否在图片范围内(避免点击到视图的空白区域) guard imageLogicX >= 0, imageLogicX <= imageSize.width, imageLogicY >= 0, imageLogicY <= imageSize.height else { print("点击位置不在图片上") return } // 4. 转换为原始图片的真实像素坐标(逻辑点 × 图片scale) let pixelX = Int(imageLogicX * targetImage.scale) let pixelY = Int(imageLogicY * targetImage.scale) print("原始图片像素坐标:x:\(pixelX), y:\(pixelY)") }
关键说明
- 为什么要乘以
targetImage.scale?因为UIImage的size属性是逻辑点,而Retina图片(@2x/@3x)的实际像素是逻辑点乘以scale。比如一张1000×1000像素的@2x图,它的size是500×500逻辑点,所以必须乘以scale才能得到真实的像素位置。 - 不同的
contentMode要对应不同的偏移量和缩放比例计算,上面的代码覆盖了最常用的几种模式,其他模式你可以根据对齐逻辑补充偏移量的计算。
内容的提问来源于stack exchange,提问作者Vahid
相关产品推荐
相关产品推荐

