Draw another image on a UIImage -

2019-08-15 07:10发布

问题:

I am trying to implement a feature that draws an image at a specific point of a UIImageView.

1.) So the user makes a photo 2.) Photo gets displayed to the user in a UIImageView in "Aspect Fit" 3.) User clicks on the UIImageView to put a image at the tapped point 4.) Combined Image is displayed

code:

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))

}

my problem: The "checkmark Image" is never at the exact point where I clicked.

I tried a lot instead of originalImage!.size.width / imageDIsplay.frame.width to get a better ratio including CGRect AVMakeRectWithAspectRatioInsideRect(CGSize aspectRatio, CGRect boundingRect);. But nothing works correctly.

What do I miss?

THANKS! Sarah

回答1:

You're definitely on the right track. It will be useful to have on hand a working utility for converting a point in image view bounds to a point in image bounds when the image is displayed in "aspect fit" content mode:

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")
        }
    }
}

Now you can obtain the tapped coordinate with respect to the original image, so you can decide where to place the checkmark image in relation to that.