As part of the .NET MAUI Community
Toolkit, we've now released version 1.0 of the CameraView. In this video
we're going to see what you can do with it. You might still know the CameraView
from back when it was implemented in the Xamarin Community Toolkit. We've had
it there, and truth be told, it wasn't always super
stable. So for the .NET Maui Community Toolkit, we've rebuilt it
from the ground up and now we have this new CameraView version 1.0 as a separate package. And actually the
separate package is called Camera, not CameraView. So that we have the ability, the
possibility in the future to add more camera stuff in there and not be
tied to just the camera view. And I say we implemented
it. But this is actually an amazing story. There has been a
company out there that has donated their time. An employee of
them was like, hey, we need this CameraView for our
project. We love the .NET MAUI Community Toolkit and
the whole community as a whole. We want to do something back. And
instead of like, you know, donating money, they wanted to donate back in time. So
they were like, we have this CameraView implementation already. We want
to give that to you. We want to work together with you to implement that in
the .NET MAUI Community Toolkit. So that's what we did, we
collaborated, and now we have the result of that camera view version
one. Let's go check it out. Okay, here in Visual Studio 2022, I
have a new .NET MAUI project as you're used to from my
videos, and we're going to add the CameraView to this. So first
let's go to our Solution Explorer to actually install the NuGet package
right here. I'm going to click my project node and then select Manage NuGet
Packages. Then you'll end up in the NuGet browser. Of course you
can do this from Visual Studio Code on Windows, on Mac, whatever you want.
We have NuGet support for Visual Studio Code now as
well. So that's super, super cool. So you can install it
through that or just add the csproj file, add a little node right there and
you're going to look for Community Toolkit because we have several, and pick Camera. Like I said, it's
going to be camera, just camera. It's just been
released version 1.0.2 because we found some little bugs in
there already. So that's at the time of recording the latest
version. And we named it Camera because we can add like all kinds of cool
stuff in here, right? You can probably imagine what that would look like. So
we're not just tied to the view, but we can do other things with the
camera. But the CameraView is definitely in there. So we're going to install
that, we're going to review the licenses, we're going to review the dependencies
that's coming in here. And you can see Android is always very
eager to bring in a lot of dependencies and that's also the
reason why we made this a separate package so that we don't force all
these dependencies on everyone whenever it's installed. You will see, you will
get a little readme right here that will tell you how to get started.
You probably just want to copy this line, UseMauiCommunityToolkitCamera, right?
So that's the line that we need to add to our MauiProgram
and then we can start using it in our XAML and we don't need to
forget the permissions that we need to add for
the camera, of course. So let's start with the MauiProgram. First go to the
Solution Explorer again, go to the MauiProgram.cs. And then here on our
builder you can see we have this little helper right here
that will say hey you need to initialize this line. Actually it's
not showing me. Oh there we go. No it's not, it's not really showing
me in the IntelliSense right here. So that might be another
bug we need to fix but it's complaining because we don't have the initializer
for the MAUI camera. So let's just do that. UseMauiCommunityToolkitCamera
and then it will automatically bring in using CommunityToolkit.Maui; here
in the top. If it doesn't do that, just add it
manually and you will be ready to go. Okay perfect. Now the other
thing, like I said, we need to do the permissions, right?
So I'm going to show you on Android today, I will make sure
that all the sample code on the repository that will be
published under the video below in the description. It will also have the
right permissions in the Info.plist for like macOS. And
if something is needed on Windows we have all the documentation on
learn.microsoft.com, the link can also be found down below. All the
permissions and everything that's needed will be in there as well. I'm just
going to show you for Android right now. So let's go back to our Solution
Explorer again. Go to the Platforms folder, then
Android and then find our Android manifest. Actually let me just
double click it. We'll get the nice graphical editor right here which lets
you set a couple of things. Also the required permissions right here and
we're going to search for camera. So scroll, scroll scroll scroll
scroll. There we go. See, so we have camera in here. Boom. Click
that and it should bring in the camera permission for our application. If you want to do
it manually you can right click on this XML file you can do open with and
then the XML editor and you will see that the camera was added
right here. You can also do it manually if that's what you want. Same
thing for iOS, Solution Explorer. Go to the iOS folder or Mac
Catalyst, the Info.plist file. I don't think we have
the permissions in the graphical editor so do again, open with XML text editor
and you will add the right key right here. Add
a little description so that your user knows why you want to use the camera
and you'll be good to go for iOS and Mac
Catalyst as well. So okay, we got that. Let's go quickly
back to readme because we need this xmlns:toolkit. I always
keep forgetting like what the actual URL is. So let's
just copy that and then we can close the readme and we can close the
NuGet browser right here. And then we can go to our MainPage.xaml in
which we're going to add the CameraView. So we have
this xmlns:x for all the MAUI types right here. And
then I'm going to add the xmlns:toolkit so that we have all the
toolkit types in here. In this case only the camera stuff.
But if you would add like the other MAUI Community Toolkits, it would be
all just this line. No need to have like multiple XML
namespaces in here, just this one line. And I'm
going to actually keep the image. I'm going to, well, let's keep it the
source with the .NET bot, that's fine. HeightRequest is also fine. Semantic
properties. I'm going to remove that because it's
not going to make any sense for what I'm going to do. And I want to give it
a little x:Name in here. I'm not going to use MVVM. Of
course, if you want to be a clean developer you probably want to
use MVVM. But I'll get to that in a minute. For now I'm going to
do it with the code behind. So let's name this my
image and then the label, the label. I'll add a
new button later. I'm just going to add
the camera view right here. So I have this image
with the .NET bot and then underneath I'm going to add the camera, CameraView.
We're going to use the Toolkit prefix and then we have the CameraView. That's
it. That's how you import the CameraView. It's going to show up
nicely now. So there we have it. And of course there is
like a good number of events, commands, properties,
everything is in here. So what do you think of like the flash, flash
mode, right, we can set that or the zoom, the zoom factor, you can
do that. Or what else do we have? Like let's
scroll through here we have events is enabled, obviously
image capture resolution. So you can set the
resolution for the image that you're going to capture. And you can also
request from the device what resolutions are
available, what cameras are available. So very, very cool stuff. Events for
whenever a media is captured, a media capture has failed.
So all kinds of things are in here that you can use. Also the
selected camera is important. I'll get to that in a minute. You can
switch between the cameras for windows, the different
cameras, but also like on a mobile device, usually like the back or the
front, right? You can select that one. So we get to that in a minute as well.
If we just do this, it's going to use the default camera,
which is usually the rear one. But the device can kind of like
decide. So that's what we are going to have a look at as well. Let's give
this an x name as well of my camera, just so we can reference it
in our code behind as well. And then what we want to do is kind of like have the media captured. So the
way this works, you want to have this event for whenever the media is
captured. So we need a button to capture the
media, obviously so that we are going to implement that. But
also then whenever that happens, that doesn't return something in
itself, you will have to go through like the media captured event. And that is also
kind of like where I didn't decide to implement this through MVVM
because we have a kind of like weird bug, if you will. I'm going to
discuss this with the team because you can use a command. We actually
have like commands, right? Oops. Yeah, command should be in here. Why is it
not showing? It's not showing for some reason.
Capture resolution? No, there should be commands in here,
but I can't find it right now. And you can use commands to actually
capture the image as well and do other things, but you will still have to
kind of like capture this event to get the actual media. And that's kind of funny because now
you're half, half using MVVM and the other half is still events. So
there's something wrong there. I'm going to talk to the team and see how we can
make that better. So we're going to use events right here just to get
you started with this. We should have this event right now. I'm going to
remove all of this old code for the old button that we
have here. We don't need that anymore. And now we have this media captured
thing and you can see we have these event arcs and in the event arcs we
have e media and that's going to be a stream with the
media that we have. So whenever you get that, you can show it in an image,
which is what we are going to do, you can send it to your
backend, you can do all kinds of things. You can save it to the file
system if that's what you want. You can do all these things. So let's
add a little button too. This is still a vertical stack layout,
right? I left that in place. So it's just going to stack it all on top of
each other. Let's add a button here. The text is going to be smile
because we're going to take a picture, right? So we need
to smile and then we're going to have the clicked event, new event
handler and we need this one. Okay, so now we have a
new event handler too. We can reference the camera view with my
camera. So in the event handler here I can say
mycamera dot. My intellisense is not really helping
me here today. Capture media I think capture media maybe I need to do a build and it will
pick up on my changes right here. Capture oh, I think it's
capture image. There we go. Now it seems the intellisense, we
got it all here. Capture image and this actually wants a cancellation token. And if you've been watching my
channel since longer times then you probably know that I've been
promising a cancellation token. It's almost becoming a running gag now,
cancellation token video for a while. So if that's still something that you
want, let me know down in the comments. This might be a nice example actually.
So capture image and here I'm going to do cancellation token. We
need to provide it, but I'm going to do cancellation token none. Whenever
you don't want to really cancel it, you can just do cancellation token
none. And here we probably want to do async because
it's an async call so we can do await. And you want to make sure
whenever we do void, you want to wrap it in a try catch so that something,
whenever something goes wrong, you actually get the exception.
Because right now the way I'm doing this, it's going to get swallowed,
right? So that's not something that you want to do in your real production code.
This is sample code. I can get away with it. Okay, so now we have that,
and whenever the image is captured, we're going to come into this event,
right? So we can do things here. And now we can say my image dot source
is image source dot from stream. And I can just say, hey, I want to
have this eternity. Well, it wasn't e dot image stream, it
was e media, but that's actually a stream, right?
We can inspect that. You can see like hey, this is a
stream, so this should work. Although I already of course prepared
this on beforehand. And just to not waste your time with showing you an
error, we want to do this from the UI thread
because this event is raised from a background
thread, right? That happens with events and this
needs to happen on the UI thread to actually update the image.
So what you want to do there is do dispatcher. You can do it the right
way, right? Like is dispatch required, right.
That's something we can kind of like request from our application. Hey, do we need
to run this on the UI thread? Yes or no? And then whenever we do you
want to do dispatcher dispatch or you can do dispatchasync? I can just do dispatch right here. And
we can say what action do you want to dispatch? Well, I want to
do set this source thing right here. So just copy that, put
that in here. And now it's going to nicely update it from
the UI thread and everything will be okay. No exceptions will be thrown. And
let's just return here so that, you know, we've done this on the UI
thread now, and whenever this is not needed, we can still update it, right?
But now we can do it from the UI thread. I don't think that will
happen in this case, but just to make sure that we're not blocking the UI
thread unnecessarily. So let's just do it like this. Obviously if you want to
do this in real code, you don't want to duplicate this and
put it in its own method or something like that. But again, sample code, I
can get away with it. Okay, so I think whenever we do this,
we should see kind of like the first things of our camera
view. So let's just run it. I have a
physical Android device right here. I'm mirroring the screen with a
application that's built into windows called Phone link, which is super
cool. You can get all kinds of like your Android notifications, all that stuff
on your Windows desktop, but only for specific Android devices.
So go check it out. But you can also cast your screen. So any moment now
the application will come up here and we'll see the first camera
view with just a few lines of code implemented in our.net
Maui application and the app is being deployed. We can see
the splash screen coming up here. So in a minute we should see also of
course like the permission so that is built in. You
don't need to request permissions manually. If that's what you need, it will do
that automatically. So let's just say, okay, only this time and you
can see, hey, there is my camera. We can see
infinite race cars right here in all my code, a little bit like behind the
scenes right here. And we can scroll a little bit down
and we, we can say smile, right? So if I click the smile button,
it should capture the image and you can see the image updating
there at the top with the image that we still have in there. So okay, this
is working perfectly. Now let's see what kind of like other
options we still have here just to give you a sense of what you can
implement more. So if you want to change the selected camera, there is
the eye camera provider that's automatically registered in the
dependency injection container. So you can do icamera provider, camera
provider and on that we can get like the
available camera. So you can do refresh
available cameras. You need to do that first. It will refresh like the list of
cameras that's in here and then you can query this available cameras
collection right here. And whenever we kind of like
simulate that, I have a thing in here you can say hey, device id, the name
is flash supported, yes or no. So you can get a couple of
things, minimum zoom factor, maximum zoom factor, position
supported resolution. So you can get all this data from the cameras right here. And it's a little bit too much. This
video will become too long. If this is something that you're
interested in selecting different cameras, let me know down in the comments below and
I will make a follow up video on how to actually do that. For now,
I'm going to skip over it and just set a couple of properties
to show you what this can do. So let's go back to my example. Let's
add some other buttons. Let's add two. Let's do like flash. So I'm going to
toggle the flash right here. Give me a new event handler for that.
And the other thing is let's do some zoom, right? Zoom is always
cool too. And do another new event handler.
Okay, flash and zoom. So let's just implement those. And right here button
one click. That was the flash. So I'm going to say
MyCamera.FlashMode = FlashMode on or off my camera? Yeah, this seems
all right. AI, let's do it. Thank you Copilot. And I think I need
to import a using statement here using CommunityToolkit.Maui.Core.Primitives;
That's kind of like where the enums and all this
stuff lives. So let's just do that. And it will import this using here
right at the top. So it will now recognize all these types here. And
whenever it's kind of like off, it turns it to on and otherwise.
Right. So this toggles the camera flash mode. We'll see that in a live demo in
a little bit. And the other thing was the zoom. So let's do my
camera dot zoom factor. Okay, zoom factor. Well, let's
do it. Let's do it. Otherwise, let's do it. Pluses
zero, one. This doesn't look correct. Okay,
double to a float. Okay, let's fix that. Let's make it a float. Okay, so now
whenever I press that button, it keeps zooming in, right? So we don't really
have a zoom out button. You probably want to make it a slider or something.
You're probably a better designer than I am. You know me, I love minimalistic
designs. So you probably want to do something better
here. But for now this is going to work. It's going to show you that it
actually zooms in. So let's deploy this again. And what we can do now is enable the
flash and enable the zoom. And we are going
to take a little bit of more pictures. So let's bring up
this screen mirroring again right here. You can see the application is
already being deployed again. And now we have a couple of extra buttons. So
okay. While using the app, that's fine. I'm not going to
give permission like all the time. You can see my kindle that's charging right
here. So I can read some more books and learn some more. And now I have smile,
I have flash and I have zoom. So let's toggle the flash. There's no
immediate feedback for that, but whenever I press smile now you can probably see
it in the camera, in the little camera there. Here in the corner you
can see that the flash is coming up right? So we have a
little flash going on here and I can also do zoom. So if I click zoom
zoom zoom zoom zoom zoom zoom zoom you can actually see the
zoom go in and if I click flash again it will disable the flash again
and I can do click smile and it will again update the picture
here at the top right? So with just a few
lines of code, I've now implemented a CameraView inside of this .NET MAUI
application. Like I already mentioned a little bit, this
is also available on Windows, on iOS, on Mac Catalyst. Check out the
documentation which is linked below as well as the sample repository that I updated with
all the permissions that are needed, which is a sample that you can deploy
to your iOS device as well if that's what you want. Thank you so
much Esri and personally Zhitao for making this possible. Esri is
the company that kind of like generously donated their time in
the form of Zhitao, who has been working together with us,
the .NET MAUI Community Toolkit team, to actually implement this feature, write
it from the ground up again, and work together with us and have a
lot of patience while we go through the reviews as time permits us. So
really really thank you. This has been amazing and I'm sure
that everyone will be super happy to actually work with this and
implement this. Let me know down in the comments what you're creating with this, what
you want to see next for the CameraView or something else. And actually I
mentioned it already. Let me know if you want to know more about that camera
provider. But I couldn't really help myself so I recorded that video as well. You can
check it out right here and I will see you for that one.