Как рисовать прямоугольники на UIImageView в Swift быстро - PullRequest
0 голосов
/ 20 марта 2020

Здравствуйте. Я пытаюсь нарисовать несколько прямоугольников на UIImage, если пользователь начинает касаться изображения и перетаскивает его в желаемое конечное положение прямоугольника, но мое решение довольно медленное, и я не знаю почему.

Итак, это моя функция рисования:

func drawRectangleOnImage(image: UIImage, pos1: CGPoint, pos2: CGPoint) -> UIImage {
    let imageSize = image.size
    let scale: CGFloat = 0
    UIGraphicsBeginImageContextWithOptions(imageSize, false, scale)

    image.draw(at: CGPoint.zero)

    let scaling = image.size.height/mainImageView.frame.height

    let rectangle = CGRect(x: pos1.x*scaling, y: pos1.y*scaling, width: abs(pos2.x-pos1.x)*scaling, height: abs(pos2.y-pos1.y)*scaling)

    UIColor.black.setFill()
    UIRectFill(rectangle)

    let newImage = UIGraphicsGetImageFromCurrentImageContext()
    UIGraphicsEndImageContext()
    return newImage!
}

, и она называется так:

override func touchesEnded(_ touches: Set<UITouch>, with event: UIEvent?) {
    if let touch = touches.first {
        let position = touch.location(in: mainImageView)
        self.endPosition = position
    }

    guard let img = mainImageView.image else {
        return
    }
    mainImageView.image = drawRectangleOnImage(image: img, pos1: self.startPosition, pos2: self.endPosition)
}

Поэтому, когда я касаюсь дисплея и рисую прямоугольник, двигая пальцем, нужно около 2 секунд, чтобы прямоугольник появился внутри симулятора. Является ли способ рисования прямоугольника устаревшим или что не так с этим кодом?

Обновление с помощью решения Matts для создания собственного UIView для этого:

import UIKit
import Foundation

class DetectionView : UIView {
    lazy var rectangles: [CGRect] = []

    lazy var tempPointStart = CGPoint(x: 0, y: 0)
    lazy var tempPointEnd = CGPoint(x: 0, y: 0)

    override init(frame: CGRect) {
        super.init(frame:frame)
        backgroundColor = .gray
        let g = UIPanGestureRecognizer(target: self, action: #selector(pan))
        self.addGestureRecognizer(g)
    }
    @objc
    func pan(_ g:UIGestureRecognizer) {
        print(g.location(in: self).x)
        switch g.state {
        case .began:
            print(g.location(in: self))
            tempPointStart = g.location(in: self)
        case .changed:
            tempPointEnd = g.location(in: self)
            self.setNeedsDisplay()
        case .ended:
            tempPointEnd = g.location(in: self)
            rectangles.append(CGRect(x: self.tempPointStart.x, y: self.tempPointStart.y, width: self.tempPointEnd.x-self.tempPointStart.x, height: self.tempPointEnd.y-self.tempPointStart.y))
            self.tempPointStart = CGPoint(x:0,y:0)
            self.tempPointEnd = CGPoint(x:0,y:0)
            self.setNeedsDisplay()
        default: break
        }
    }
    required init?(coder aDecoder: NSCoder) {
        super.init(coder: aDecoder)
    }
    override func draw(_ rect: CGRect) {
        let con = UIGraphicsGetCurrentContext()!

        //user is still drawing
        if(self.tempPointStart.x != self.tempPointEnd.x || self.tempPointStart.y != self.tempPointEnd.y) {

            for rect in rectangles {
                con.addRect(rect)
            }

            con.addRect(CGRect(x: self.tempPointStart.x, y: self.tempPointStart.y, width: self.tempPointEnd.x-self.tempPointStart.x, height: self.tempPointEnd.y-self.tempPointStart.y))
        }
        else {
            for rect in rectangles {
                con.addRect(rect)
            }
        }

        con.strokePath()
    }
}

Итак в UIView это работает довольно хорошо, но теперь моя проблема в том, что я не знаю, как добавить изображение к этому представлению элегантным способом. Я пытался реализовать его как UIImageView, но затем функциональность рисования прямоугольников была потеряна. Я мог бы загрузить его как фоновое изображение для этого представления, но я не уверен, насколько хорошо это будет работать, потому что изображения могут быть в любом формате, поэтому я должен быть осторожен с форматами изображений.

У вас есть идея загрузить изображение в это представление элегантным способом?

...