Hey everybody this is calum and we're going to make like the paparazzi and take some photos in this
video.
In the last video I said we were going to add a tap gesture recognizer to take a photo and we didn't.
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
screen.
OK.
Pretty cool.
So let's get started.
Pull open that X code project and just like before we were working with a capture session a camera output
and a preview layer.
Now to save that photo we're going to need to use our camera output.
OK.
And we're going to save whatever gets added to the layer to a UI image.
OK.
So let's go ahead and beneath you will appear we're going to create a function called did tap camera
view and we're going to use our tap gesture later to call this function whenever the screen is tapped.
So go ahead and type phunk did tap camera view.
And what we're going to do is we're first going to set up some avi capture settings.
So go ahead and type let settings and make that equal to AVI capture photo settings.
OK now we're going to instantiate those.
And now we're going to actually set up the settings to have the right information and in order to do
that we're going to go ahead and create two things.
One thing is called a preview pixel type which I'll show you what that is in a second and we're going
to create a preview format.
So let's go ahead and let's type let preview pixel type and we're going to go ahead and set that to
be equal to settings available.
Preview photo pixel format types and we're going to just choose the first one in that array.
So as you can see here this array is an array of an S number and it's an array of pixel format types
compatible with the photo settings.
Now the first property is pretty much like a just a generic photo.
You can do some other fancy stuff with live photos and HDR photos and whatever else.
But first just return to your basic iOS photo.
So we're just going to use the first item in this array of an S number.
So go ahead and type let preview format and this is going to be equal to a dictionary.
Now I'm going to type a lot of things and then I'll explain them afterwards.
So first go ahead and type case C-v pixel buffer pixel format key whereas that pixel format type key.
Awesome.
Now we need to actually cast this as a string and then we're going to go ahead and for the value that
so this is the key the pixel pixel by pixel format type key.
That is the key and we're going to set the value to be equal to our preview pixel type that we just
made.
Now if you click this you'll see that it is a type of C-f string K which comes from core video.
But we're just casting it as an ordinary string.
All right so that is the first item in our dictionary.
Next we're going to set up a secondary one so k C.V pixel buffer with key.
All righty.
We need to cast that as a string as well.
And the value is going to be 160.
Next we're going to go ahead and type Casey.
Casey V pixel buffer height key cast that as a string and set that to be 160 as well.
Now I know that looks like a bunch of jargon but I'll show you how to use it right now.
So go ahead and type settings.
This is going to just be added as a setting for how we capture our image type settings preview photo
format.
And we're going to give it our preview format that we just made.
Now if you look at the definition of this you can see that it requires a dictionary of string and any.
Now what it is is it's a dictionary describing the format for delivery of pre-view sized images.
And that's going to be really important because the image that we pass to our image you it doesn't need
to be the full 19:20 by 10 80 resolution.
It can be preview sized And so this is going to set it up so that it's a preview sized image thus making
our app a little more efficient and take up less space.
Kind of cool.
So it makes like a thumbnail sized image for us which is exactly what we want.
So after this what we're going to do is we're going to go ahead and type camera output and we're going
to go ahead and type capture photo K camera output is from here we've already registered it as an output
and we're going to use our input to then capture a photo.
Now it says here with Avi photo capture settings we've got that.
That's our settings and our delegate is going to be self.
But you're probably wondering we haven't we haven't conformed to any protocols.
We haven't added any extensions and it tells us this now it gets angry with us it says does not conform
to AVI photo capture delegate.
That is where we are going to go ahead and conform so that we can actually use A-V photo capture delegate
Syrie
helpful but not helpful Apparently I thought I said its name but I didn't.
So anyway let's move on.
We're going to create an extension of Avi capture photo capture delegate.
So go ahead and type extension camera Visi and Avi capture photo capture or delegate.
All right.
And I like to put things like this into extensions instead of conforming to them up here.
I just personally prefer doing it that way.
What we need to do is we need to call one of the important delegate methods from Avi capture photo capture
delegate.
And that's called photo output.
But we need to do.
Did finish processing photo.
It's the first one that shows up right there.
And you can see that we get an output of Avi capture photo output.
We get a photo of type avi capture photo and we can also get an error if something goes wrong.
So first what we're going to do is we're going to go ahead and say if let error equals error.
If there's an error we're going to set a value here called air and we're going to go ahead and debug.
Print that error already and it'll tell us what went wrong.
If there are no errors then we're going to do is we're going to basically use the photo data captured
in this avi capture photo.
But in order to do that we actually need to create a variable first that we're going to use to set that
data to show up at the very very tippy top.
Go ahead and create a variable called photo data and make it of type data.
But we're going to optionally unwrap it because it does not have a value and at that point our app doesn't
know whether it has a value or not.
But to make sure that it does we're going to actually give it a value now.
So now that we have something that can hold our photo data we're actually going to go ahead and type
photo K. pulling from this delegate method.
Photo dot file whoopsies file data representation.
Now you'll notice that this function returns data.
So we're basically getting the photo data and we're saving it here.
Now if you know anything about you I image you know that you can create a UI image from data which is
perfect.
So we're going to do that.
Let image equals UI image.
Check it out from data and we can just pass in our photo data.
Pretty cool right now that we have an image you know we can do we can call self capture image view that
image and we can pass in our image.
Although look at this it's giving us an error remember photo data is an optional at first so we need
to force unwrap it.
Now that we know that it has a photo data representation and we just basically converted what we get
from our screen the output turns into photo data the photo data turns into an image and we pass that
image into our image view.
So I don't know about you but I'm going to go check it out and see if it worked.
Oh but you know what we can't.
We have not set up our tap gesture to capture a photo.
Let's do that now.
So what we're going to do is basically we're going to set up this tap gesture as soon as the view appears
so that when we tap on the camera view it's going to let us take a photo.
Ok it's really easy takes almost no code.
Let's go ahead and do it.
Let tap equals you.
Tap gesture recognizer.
Easy enough right.
But of course we need to give it a target and an action.
So the target itself and we'll set that up in a second and the action go ahead and type pound sign selector.
And then what we're going to do is inside of this we're going to call did tap camera view.
OK.
So our tap gesture is good to go.
And we're going to set it up so that it only requires a single tap to take a photo.
So to do that.
Go ahead and type tap DOT number of taps required and set that speak to one.
OK.
Easy enough right now.
The last thing we need to do is we actually need to pin this to our camera view.
So after we add the sub layer go ahead and type camera view whoopsies camera view dot add gesture recognizer
and just pass in tap.
Easy as that.
So now when we tap on our screen one time will look at this error and just the second now when we tap
on our screen one time it's going to go ahead and call did tap camera view take a photo capture it and
set our image view.
But it's giving us an error here.
It's saying argument of selector refers to instance method did tap camera view.
That is not exposed to objective.
Now what we need to do is to add at oh BJC to expose it to Objective-C.
If we click fix it there we go.
Did it do it OK.
Yes.
So you'll notice that this function now says oh BJC phunk did tap camera view.
Now if you go ahead and try to build this you'll notice let's just make sure it builds.
Yeah.
So it works.
Now it basically can use this tap gesture recognizer with our function.
Let's go give it a shot.
Let's see if it worked.
All right our app is building it's running.
Here we go.
So when I tap on the screen you should see it show up in the bottom right in our image you will see
if it worked.
Look at that it worked.
Take a photo of that boom take a photo of that boom.
Love it.
OK so guys this works we're capturing an image.
We have a tap gesture working properly to show the image beautiful.
In the next video we're going to start getting into core m-L.
We're going to use this image to pass into a train model to make predictions to tell us what it thinks
it is.
I'm so excited.
Let's go ahead and move over to the next video.
Awesome job with this one.