Swift:绘图开始时图像丢失的长宽比

时间:2018-09-02 04:57:21

标签: swift

我正在尝试为我的应用制作图像编辑VC,并且遇到了上述问题。每当我开始在图像上绘画时,图像都会扭曲然后失去宽高比。

Gif:

enter image description here

我的完整代码如下:

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

1 个答案:

答案 0 :(得分:0)

问题在这里:

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

您正在使用图像视图的框架绘制图像。 这会拉伸图像。

您需要绘制图像,就像 contentMode.scaleAspectFit

为此,首先确定图像的宽高比(W:H)。您可以通过访问size的{​​{1}}属性来执行此操作。将此比例与图像视图的纵横比进行比较。

如果图像的比例小于视图的比例,则表示绘制图像的高度可以与图像的视图高度相同,并且可以使用图像的纵横比来计算图像的宽度。 / p>

如果图像的比例大于视图的比例,则意味着绘制图像的宽度可以与图像视图的宽度相同,并且可以计算图像的高度,