1
00:00:07,980 --> 00:00:12,880
Hey everybody this is calum and we're going to make like the paparazzi and take some photos in this

2
00:00:12,880 --> 00:00:13,690
video.

3
00:00:13,690 --> 00:00:18,690
In the last video I said we were going to add a tap gesture recognizer to take a photo and we didn't.

4
00:00:18,700 --> 00:00:22,960
So we're going to do that in this video then we're going to save that photo to the image of you on the

5
00:00:22,960 --> 00:00:23,630
screen.

6
00:00:23,630 --> 00:00:23,820
OK.

7
00:00:23,830 --> 00:00:24,880
Pretty cool.

8
00:00:24,880 --> 00:00:26,670
So let's get started.

9
00:00:26,680 --> 00:00:33,970
Pull open that X code project and just like before we were working with a capture session a camera output

10
00:00:34,000 --> 00:00:35,850
and a preview layer.

11
00:00:35,850 --> 00:00:39,900
Now to save that photo we're going to need to use our camera output.

12
00:00:40,040 --> 00:00:40,570
OK.

13
00:00:40,840 --> 00:00:46,160
And we're going to save whatever gets added to the layer to a UI image.

14
00:00:46,350 --> 00:00:46,860
OK.

15
00:00:47,080 --> 00:00:54,040
So let's go ahead and beneath you will appear we're going to create a function called did tap camera

16
00:00:54,040 --> 00:00:59,950
view and we're going to use our tap gesture later to call this function whenever the screen is tapped.

17
00:00:59,950 --> 00:01:04,840
So go ahead and type phunk did tap camera view.

18
00:01:05,170 --> 00:01:09,480
And what we're going to do is we're first going to set up some avi capture settings.

19
00:01:09,520 --> 00:01:17,340
So go ahead and type let settings and make that equal to AVI capture photo settings.

20
00:01:17,380 --> 00:01:20,130
OK now we're going to instantiate those.

21
00:01:20,140 --> 00:01:26,290
And now we're going to actually set up the settings to have the right information and in order to do

22
00:01:26,290 --> 00:01:28,660
that we're going to go ahead and create two things.

23
00:01:28,660 --> 00:01:33,280
One thing is called a preview pixel type which I'll show you what that is in a second and we're going

24
00:01:33,280 --> 00:01:35,740
to create a preview format.

25
00:01:35,740 --> 00:01:44,890
So let's go ahead and let's type let preview pixel type and we're going to go ahead and set that to

26
00:01:44,890 --> 00:01:48,400
be equal to settings available.

27
00:01:48,700 --> 00:01:55,810
Preview photo pixel format types and we're going to just choose the first one in that array.

28
00:01:55,810 --> 00:02:02,940
So as you can see here this array is an array of an S number and it's an array of pixel format types

29
00:02:02,950 --> 00:02:04,660
compatible with the photo settings.

30
00:02:04,660 --> 00:02:09,310
Now the first property is pretty much like a just a generic photo.

31
00:02:09,310 --> 00:02:13,600
You can do some other fancy stuff with live photos and HDR photos and whatever else.

32
00:02:13,720 --> 00:02:17,610
But first just return to your basic iOS photo.

33
00:02:17,680 --> 00:02:21,640
So we're just going to use the first item in this array of an S number.

34
00:02:21,640 --> 00:02:26,710
So go ahead and type let preview format and this is going to be equal to a dictionary.

35
00:02:26,710 --> 00:02:29,860
Now I'm going to type a lot of things and then I'll explain them afterwards.

36
00:02:29,860 --> 00:02:40,330
So first go ahead and type case C-v pixel buffer pixel format key whereas that pixel format type key.

37
00:02:40,330 --> 00:02:40,870
Awesome.

38
00:02:41,020 --> 00:02:48,840
Now we need to actually cast this as a string and then we're going to go ahead and for the value that

39
00:02:48,860 --> 00:02:52,990
so this is the key the pixel pixel by pixel format type key.

40
00:02:53,230 --> 00:02:58,450
That is the key and we're going to set the value to be equal to our preview pixel type that we just

41
00:02:58,450 --> 00:02:59,350
made.

42
00:02:59,350 --> 00:03:04,570
Now if you click this you'll see that it is a type of C-f string K which comes from core video.

43
00:03:04,720 --> 00:03:07,840
But we're just casting it as an ordinary string.

44
00:03:07,840 --> 00:03:11,190
All right so that is the first item in our dictionary.

45
00:03:11,200 --> 00:03:18,290
Next we're going to set up a secondary one so k C.V pixel buffer with key.

46
00:03:18,560 --> 00:03:19,130
All righty.

47
00:03:19,240 --> 00:03:21,720
We need to cast that as a string as well.

48
00:03:21,940 --> 00:03:25,750
And the value is going to be 160.

49
00:03:25,750 --> 00:03:28,960
Next we're going to go ahead and type Casey.

50
00:03:28,960 --> 00:03:38,200
Casey V pixel buffer height key cast that as a string and set that to be 160 as well.

51
00:03:38,200 --> 00:03:42,170
Now I know that looks like a bunch of jargon but I'll show you how to use it right now.

52
00:03:42,250 --> 00:03:44,130
So go ahead and type settings.

53
00:03:44,170 --> 00:03:50,380
This is going to just be added as a setting for how we capture our image type settings preview photo

54
00:03:50,380 --> 00:03:51,340
format.

55
00:03:51,580 --> 00:03:55,980
And we're going to give it our preview format that we just made.

56
00:03:55,990 --> 00:04:03,110
Now if you look at the definition of this you can see that it requires a dictionary of string and any.

57
00:04:03,110 --> 00:04:09,100
Now what it is is it's a dictionary describing the format for delivery of pre-view sized images.

58
00:04:09,220 --> 00:04:14,680
And that's going to be really important because the image that we pass to our image you it doesn't need

59
00:04:14,680 --> 00:04:17,930
to be the full 19:20 by 10 80 resolution.

60
00:04:18,040 --> 00:04:23,230
It can be preview sized And so this is going to set it up so that it's a preview sized image thus making

61
00:04:23,290 --> 00:04:26,060
our app a little more efficient and take up less space.

62
00:04:26,080 --> 00:04:26,760
Kind of cool.

63
00:04:26,860 --> 00:04:31,150
So it makes like a thumbnail sized image for us which is exactly what we want.

64
00:04:31,150 --> 00:04:36,700
So after this what we're going to do is we're going to go ahead and type camera output and we're going

65
00:04:36,700 --> 00:04:42,670
to go ahead and type capture photo K camera output is from here we've already registered it as an output

66
00:04:43,060 --> 00:04:46,340
and we're going to use our input to then capture a photo.

67
00:04:46,360 --> 00:04:50,290
Now it says here with Avi photo capture settings we've got that.

68
00:04:50,290 --> 00:04:55,240
That's our settings and our delegate is going to be self.

69
00:04:55,540 --> 00:04:59,440
But you're probably wondering we haven't we haven't conformed to any protocols.

70
00:04:59,440 --> 00:05:05,680
We haven't added any extensions and it tells us this now it gets angry with us it says does not conform

71
00:05:05,890 --> 00:05:08,170
to AVI photo capture delegate.

72
00:05:08,370 --> 00:05:15,180
That is where we are going to go ahead and conform so that we can actually use A-V photo capture delegate

73
00:05:16,170 --> 00:05:16,860
Syrie

74
00:05:19,570 --> 00:05:22,880
helpful but not helpful Apparently I thought I said its name but I didn't.

75
00:05:22,900 --> 00:05:24,100
So anyway let's move on.

76
00:05:24,370 --> 00:05:29,100
We're going to create an extension of Avi capture photo capture delegate.

77
00:05:29,200 --> 00:05:39,040
So go ahead and type extension camera Visi and Avi capture photo capture or delegate.

78
00:05:39,040 --> 00:05:39,340
All right.

79
00:05:39,340 --> 00:05:44,160
And I like to put things like this into extensions instead of conforming to them up here.

80
00:05:44,170 --> 00:05:46,310
I just personally prefer doing it that way.

81
00:05:46,330 --> 00:05:50,980
What we need to do is we need to call one of the important delegate methods from Avi capture photo capture

82
00:05:50,980 --> 00:05:51,420
delegate.

83
00:05:51,430 --> 00:05:53,730
And that's called photo output.

84
00:05:53,890 --> 00:05:54,590
But we need to do.

85
00:05:54,590 --> 00:05:56,990
Did finish processing photo.

86
00:05:57,160 --> 00:05:58,950
It's the first one that shows up right there.

87
00:05:59,140 --> 00:06:02,920
And you can see that we get an output of Avi capture photo output.

88
00:06:02,920 --> 00:06:08,070
We get a photo of type avi capture photo and we can also get an error if something goes wrong.

89
00:06:08,080 --> 00:06:15,620
So first what we're going to do is we're going to go ahead and say if let error equals error.

90
00:06:15,690 --> 00:06:22,140
If there's an error we're going to set a value here called air and we're going to go ahead and debug.

91
00:06:22,140 --> 00:06:26,840
Print that error already and it'll tell us what went wrong.

92
00:06:27,000 --> 00:06:33,450
If there are no errors then we're going to do is we're going to basically use the photo data captured

93
00:06:33,810 --> 00:06:35,550
in this avi capture photo.

94
00:06:35,640 --> 00:06:41,950
But in order to do that we actually need to create a variable first that we're going to use to set that

95
00:06:42,120 --> 00:06:45,350
data to show up at the very very tippy top.

96
00:06:45,420 --> 00:06:50,670
Go ahead and create a variable called photo data and make it of type data.

97
00:06:50,670 --> 00:06:55,260
But we're going to optionally unwrap it because it does not have a value and at that point our app doesn't

98
00:06:55,260 --> 00:06:57,210
know whether it has a value or not.

99
00:06:57,210 --> 00:07:00,720
But to make sure that it does we're going to actually give it a value now.

100
00:07:00,900 --> 00:07:05,550
So now that we have something that can hold our photo data we're actually going to go ahead and type

101
00:07:05,550 --> 00:07:09,290
photo K. pulling from this delegate method.

102
00:07:09,450 --> 00:07:15,240
Photo dot file whoopsies file data representation.

103
00:07:15,240 --> 00:07:18,750
Now you'll notice that this function returns data.

104
00:07:18,750 --> 00:07:23,680
So we're basically getting the photo data and we're saving it here.

105
00:07:23,760 --> 00:07:28,650
Now if you know anything about you I image you know that you can create a UI image from data which is

106
00:07:28,650 --> 00:07:29,350
perfect.

107
00:07:29,400 --> 00:07:30,580
So we're going to do that.

108
00:07:30,700 --> 00:07:33,960
Let image equals UI image.

109
00:07:33,960 --> 00:07:39,010
Check it out from data and we can just pass in our photo data.

110
00:07:39,090 --> 00:07:47,640
Pretty cool right now that we have an image you know we can do we can call self capture image view that

111
00:07:47,640 --> 00:07:50,660
image and we can pass in our image.

112
00:07:50,910 --> 00:07:56,730
Although look at this it's giving us an error remember photo data is an optional at first so we need

113
00:07:56,730 --> 00:07:57,610
to force unwrap it.

114
00:07:57,610 --> 00:08:03,840
Now that we know that it has a photo data representation and we just basically converted what we get

115
00:08:03,840 --> 00:08:09,480
from our screen the output turns into photo data the photo data turns into an image and we pass that

116
00:08:09,480 --> 00:08:11,300
image into our image view.

117
00:08:11,520 --> 00:08:14,840
So I don't know about you but I'm going to go check it out and see if it worked.

118
00:08:14,910 --> 00:08:16,410
Oh but you know what we can't.

119
00:08:16,410 --> 00:08:20,680
We have not set up our tap gesture to capture a photo.

120
00:08:20,760 --> 00:08:21,730
Let's do that now.

121
00:08:22,110 --> 00:08:26,980
So what we're going to do is basically we're going to set up this tap gesture as soon as the view appears

122
00:08:27,230 --> 00:08:31,000
so that when we tap on the camera view it's going to let us take a photo.

123
00:08:31,050 --> 00:08:34,290
Ok it's really easy takes almost no code.

124
00:08:34,290 --> 00:08:35,660
Let's go ahead and do it.

125
00:08:35,800 --> 00:08:37,550
Let tap equals you.

126
00:08:37,560 --> 00:08:39,300
Tap gesture recognizer.

127
00:08:39,420 --> 00:08:40,500
Easy enough right.

128
00:08:40,800 --> 00:08:43,560
But of course we need to give it a target and an action.

129
00:08:43,620 --> 00:08:50,860
So the target itself and we'll set that up in a second and the action go ahead and type pound sign selector.

130
00:08:51,150 --> 00:08:56,600
And then what we're going to do is inside of this we're going to call did tap camera view.

131
00:08:56,700 --> 00:08:57,520
OK.

132
00:08:57,720 --> 00:08:59,490
So our tap gesture is good to go.

133
00:08:59,760 --> 00:09:03,480
And we're going to set it up so that it only requires a single tap to take a photo.

134
00:09:03,540 --> 00:09:04,110
So to do that.

135
00:09:04,110 --> 00:09:09,320
Go ahead and type tap DOT number of taps required and set that speak to one.

136
00:09:09,490 --> 00:09:09,690
OK.

137
00:09:09,690 --> 00:09:11,560
Easy enough right now.

138
00:09:11,610 --> 00:09:16,250
The last thing we need to do is we actually need to pin this to our camera view.

139
00:09:16,320 --> 00:09:27,060
So after we add the sub layer go ahead and type camera view whoopsies camera view dot add gesture recognizer

140
00:09:27,630 --> 00:09:29,220
and just pass in tap.

141
00:09:29,220 --> 00:09:30,110
Easy as that.

142
00:09:30,300 --> 00:09:36,900
So now when we tap on our screen one time will look at this error and just the second now when we tap

143
00:09:36,900 --> 00:09:44,070
on our screen one time it's going to go ahead and call did tap camera view take a photo capture it and

144
00:09:44,070 --> 00:09:45,290
set our image view.

145
00:09:45,510 --> 00:09:46,990
But it's giving us an error here.

146
00:09:47,090 --> 00:09:51,890
It's saying argument of selector refers to instance method did tap camera view.

147
00:09:51,890 --> 00:09:54,120
That is not exposed to objective.

148
00:09:54,150 --> 00:09:59,350
Now what we need to do is to add at oh BJC to expose it to Objective-C.

149
00:09:59,460 --> 00:10:03,710
If we click fix it there we go.

150
00:10:03,710 --> 00:10:05,250
Did it do it OK.

151
00:10:05,290 --> 00:10:05,590
Yes.

152
00:10:05,590 --> 00:10:10,440
So you'll notice that this function now says oh BJC phunk did tap camera view.

153
00:10:10,450 --> 00:10:16,220
Now if you go ahead and try to build this you'll notice let's just make sure it builds.

154
00:10:16,490 --> 00:10:16,760
Yeah.

155
00:10:16,810 --> 00:10:17,560
So it works.

156
00:10:17,590 --> 00:10:23,270
Now it basically can use this tap gesture recognizer with our function.

157
00:10:23,320 --> 00:10:24,120
Let's go give it a shot.

158
00:10:24,130 --> 00:10:25,550
Let's see if it worked.

159
00:10:29,010 --> 00:10:31,710
All right our app is building it's running.

160
00:10:31,740 --> 00:10:32,400
Here we go.

161
00:10:32,400 --> 00:10:38,700
So when I tap on the screen you should see it show up in the bottom right in our image you will see

162
00:10:38,700 --> 00:10:39,350
if it worked.

163
00:10:41,240 --> 00:10:42,420
Look at that it worked.

164
00:10:42,440 --> 00:10:46,030
Take a photo of that boom take a photo of that boom.

165
00:10:46,130 --> 00:10:46,650
Love it.

166
00:10:46,670 --> 00:10:49,850
OK so guys this works we're capturing an image.

167
00:10:49,850 --> 00:10:54,110
We have a tap gesture working properly to show the image beautiful.

168
00:10:54,230 --> 00:10:57,060
In the next video we're going to start getting into core m-L.

169
00:10:57,090 --> 00:11:02,660
We're going to use this image to pass into a train model to make predictions to tell us what it thinks

170
00:11:02,660 --> 00:11:02,930
it is.

171
00:11:02,930 --> 00:11:03,770
I'm so excited.

172
00:11:03,770 --> 00:11:05,930
Let's go ahead and move over to the next video.

173
00:11:05,930 --> 00:11:07,280
Awesome job with this one.
