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