-
Notifications
You must be signed in to change notification settings - Fork 0
Expand file tree
/
Copy pathDrawView.swift
More file actions
executable file
·93 lines (72 loc) · 3.03 KB
/
DrawView.swift
File metadata and controls
executable file
·93 lines (72 loc) · 3.03 KB
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
/*
Copyright (C) 2016 Apple Inc. All Rights Reserved.
See LICENSE.txt for this sample’s licensing information
Abstract:
This file has routines for drwaing and detecting user touches (input digit)
*/
import UIKit
/**
This class is used to handle the drawing in the DigitView so we can get user input digit,
This class doesn't really have an MPS or Metal going in it, it is just used to get user input
*/
class DrawView: UIView {
// some parameters of how thick a line to draw 15 seems to work
// and we have white drawings on black background just like MNIST needs its input
var linewidth = CGFloat(15) { didSet { setNeedsDisplay() } }
var color = UIColor.white { didSet { setNeedsDisplay() } }
// we will keep touches made by user in view in these as a record so we can draw them.
var lines: [Line] = []
var lastPoint: CGPoint!
override func touchesBegan(_ touches: Set<UITouch>, with event: UIEvent?) {
lastPoint = touches.first!.location(in: self)
}
override func touchesMoved(_ touches: Set<UITouch>, with event: UIEvent?) {
let newPoint = touches.first!.location(in: self)
// keep all lines drawn by user as touch in record so we can draw them in view
lines.append(Line(start: lastPoint, end: newPoint))
lastPoint = newPoint
// make a draw call
setNeedsDisplay()
}
override func draw(_ rect: CGRect) {
super.draw(rect)
let drawPath = UIBezierPath()
drawPath.lineCapStyle = .round
for line in lines{
drawPath.move(to: line.start)
drawPath.addLine(to: line.end)
}
drawPath.lineWidth = linewidth
color.set()
drawPath.stroke()
}
/**
This function gets the pixel data of the view so we can put it in MTLTexture
- Returns:
Void
*/
func getViewContext() -> CGContext? {
// our network takes in only grayscale images as input
let colorSpace:CGColorSpace = CGColorSpaceCreateDeviceGray()
// we have 3 channels no alpha value put in the network
let bitmapInfo = CGImageAlphaInfo.none.rawValue
// this is where our view pixel data will go in once we make the render call
let context = CGContext(data: nil, width: 28, height: 28, bitsPerComponent: 8, bytesPerRow: 28, space: colorSpace, bitmapInfo: bitmapInfo)
// scale and translate so we have the full digit and in MNIST standard size 28x28
context!.translateBy(x: 0 , y: 28)
context!.scaleBy(x: 28/self.frame.size.width, y: -28/self.frame.size.height)
// put view pixel data in context
self.layer.render(in: context!)
return context
}
}
/**
2 points can give a line and this class is just for that purpose, it keeps a record of a line
*/
class Line{
var start, end: CGPoint
init(start: CGPoint, end: CGPoint) {
self.start = start
self.end = end
}
}