[Swift] MacOS 그림판 앱 만들기 - 선 그리기

빛트·2022년 6월 13일
2

MACOS-SWIFT-CANVAS

목록 보기
1/3
post-thumbnail

언젠가 전자칠판 프로젝트를 준비하며 만들었던 그림판 앱입니다
( 프로젝트는 엎어졌다고 합니다 ... )


일단 그려~!

Canvas는 마우스 드래그 이벤트마다 선을 그리는 메서드를 호출합니다

class Canvas: NSView {
    var lastPoint = CGPoint.zero;
    var mode : CGBlendMode = .normal;

    @IBOutlet var imageView: NSImageView!;

    @IBAction func onClickEraseButton(_ sender: Any){
        self.mode = .clear
    }

    @IBAction func onClickDrawButton(_ sender: Any){
        self.mode = .normal
    }

    override func draw(_ dirtyRect: NSRect) {
        super.draw(dirtyRect)
    }

    override func mouseDown(with event: NSEvent) {
        lastPoint = CGPoint(x: event.locationInWindow.x, y: event.locationInWindow.y)
    }

    override func mouseDragged(with event: NSEvent) {
        let currentPoint = CGPoint(x: event.locationInWindow.x, y: event.locationInWindow.y)
    
        self.drawLine( from: self.lastPoint, to: currentPoint)
        self.lastPoint = currentPoint
    }
}

이 메서드는 직전 이벤트에서 저장된 이미지를 뷰 위에 그린 후, 그 위에 선을 그립니다

그리고, 다시 이 화면을 이미지화하여 저장합니다

extension Canvas {
    func drawLine(from: CGPoint, to: CGPoint){
        let compression_factor = 1
        let options: [NSBitmapImageRep.PropertyKey: Any] = [.compressionFactor: compression_factor]
    
        guard let rep = bitmapImageRepForCachingDisplay(in: self.bounds) else { return }
        guard let context = NSGraphicsContext(bitmapImageRep: rep) else { return }

        NSGraphicsContext.current = context

        self.imageView.image?.draw(in: self.bounds) 
    
        let cgContext = context.cgContext

        cgContext.move(to: from)
        cgContext.addLine(to: to)

        cgContext.setLineCap(.round)
        cgContext.setLineWidth(5)
        cgContext.setStrokeColor(NSColor.red.cgColor)
        cgContext.setBlendMode(mode)
        cgContext.strokePath()

        if let data = rep.representation(using: .png, properties: options) {
            imageView.image = NSImage(data: data)!
        }
    }
}

하지만, 성능 이슈

이렇게 빠르게 선을 그리게 되면,

CPU 사용량이 빠르게 올라가는 것을 확인할 수 있었습니다

NSView의 draw(_ rect:) 메서드를 이용하기로 했습니다

0개의 댓글