Swift:开始绘制时图像丢失纵横比

8fsztsew  于 2022-12-22  发布在  Swift
关注(0)|答案(1)|浏览(158)

我正在尝试为我的应用程序制作一个图像编辑VC,遇到了上面的问题。每当我开始在我的图像上绘图时,图像就会扭曲,然后失去高宽比。
GIF是:

我的完整代码是:

class DrawImageController: UIViewController {
    
    var canvasImageView: UIImageView = {
        let iv = UIImageView()
        iv.translatesAutoresizingMaskIntoConstraints = false
        iv.backgroundColor = .yellow
        iv.contentMode = .scaleAspectFit
        return iv
    }()
    
    var lastTouch = CGPoint.zero
    
    override func viewDidLoad() {
        super.viewDidLoad()
        setupViews()
    }
    
    func setupViews() {
        view.backgroundColor = .black

        view.addSubview(canvasImageView)
        
        canvasImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
        canvasImageView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
        canvasImageView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
        canvasImageView.heightAnchor.constraint(equalToConstant: 300).isActive = true
        
        canvasImageView.image = UIImage(named: "testImage")
    }
    
    override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let firstTouch = touches.first {
            lastTouch = firstTouch.location(in: canvasImageView)
        }
    }
    
    override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
        if let firstTouch = touches.first {
            let touchLocation = firstTouch.location(in: canvasImageView)
            drawLine(from: lastTouch, to: touchLocation)
            lastTouch = touchLocation
        }
    }

    func drawLine(from: CGPoint, to: CGPoint) {
        UIGraphicsBeginImageContext(canvasImageView.frame.size)
        
        if let context = UIGraphicsGetCurrentContext() {
            canvasImageView.image?.draw(in: CGRect(x: 0, y: 0, width: canvasImageView.frame.size.width, height: canvasImageView.frame.size.height))

            context.move(to: from)
            context.addLine(to: to)
            
            context.setLineCap(.round)
            context.setLineWidth(5.0)
            context.setStrokeColor(UIColor.blue.cgColor)
            
            context.strokePath()
            
            let image = UIGraphicsGetImageFromCurrentImageContext()
            canvasImageView.image = image
            UIGraphicsEndImageContext()
        }          
    }
}

我从YouTube、GitHub和SO上的各种教程中改编了我的绘制方法。我哪里出了问题?

已解决

根据@Sweeper的建议,我修改了setupViews()drawLine中的代码,以考虑图像和imageView的纵横比。

func setupViews() {
    view.backgroundColor = .black

    view.addSubview(canvasImageView)
    
    canvasImageView.centerYAnchor.constraint(equalTo: view.centerYAnchor).isActive = true
    canvasImageView.leadingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.leadingAnchor).isActive = true
    canvasImageView.trailingAnchor.constraint(equalTo: view.safeAreaLayoutGuide.trailingAnchor).isActive = true
    
    let aspectRatio = getImageAspectRatio(image: UIImage(named: "testImage")!)
    let screenWidth = UIScreen.main.bounds.width
    let height = CGFloat(1.0) / aspectRatio * screenWidth
    canvasImageView.heightAnchor.constraint(equalToConstant: height).isActive = true

    canvasImageView.image = UIImage(named: "testImage")
}

func drawLine(from: CGPoint, to: CGPoint) {

    UIGraphicsBeginImageContext(canvasImageView.frame.size)
    
    guard let context = UIGraphicsGetCurrentContext() else {return}
    
    if let canvasImage = canvasImageView.image {
        let imageViewAspectRatio = getAspectRatio(frame: canvasImageView.frame)
        let imageAspectRatio = getImageAspectRatio(image: canvasImage)
        
        if imageViewAspectRatio > imageAspectRatio {
            canvasImageView.image?.draw(in: CGRect(x: 0, y: 0, width: imageAspectRatio * canvasImageView.frame.size.height, height: canvasImageView.frame.size.height))
        } else if imageViewAspectRatio < imageAspectRatio {
            canvasImageView.image?.draw(in: CGRect(x: 0, y: 0, width: canvasImageView.frame.size.width, height: CGFloat(1.0) / imageAspectRatio * canvasImageView.frame.size.width))
        } else {
            canvasImageView.image?.draw(in: CGRect(x: 0, y: 0, width: canvasImageView.frame.size.width, height: canvasImageView.frame.size.height))
        }
        
        context.move(to: from)
        context.addLine(to: to)
        
        context.setLineCap(.round)
        context.setLineWidth(5.0)
        context.setStrokeColor(UIColor.blue.cgColor)
        
        context.strokePath()
        
        let image = UIGraphicsGetImageFromCurrentImageContext()
        canvasImageView.image = image
        UIGraphicsEndImageContext()
    }
}
bxgwgixi

bxgwgixi1#

问题就在这里:

canvasImageView.image?.draw(in: CGRect(x: 0, y: 0, width: canvasImageView.frame.size.width, height: canvasImageView.frame.size.height))

您正在使用图像视图的框架绘制图像。* 这将拉伸图像。*
您需要绘制图像 *,就好像 * contentMode.scaleAspectFit一样。
为此,首先确定图像的纵横比(W:H)。您可以通过访问UIImagesize属性来执行此操作。将此比率与图像视图的纵横比进行比较。
如果图像的比率小于视图的比率,则意味着绘制图像的高度可以与图像视图高度相同,并且可以使用图像的纵横比计算图像宽度。
如果图像的比率大于视图的比率,则意味着绘制图像的宽度可以与图像视图宽度相同,并且可以计算图像高度,

相关问题