I am back to finish off the data selfie app with one more
feature, and that feature is adding something else
to the database-- namely, an image from the webcam.
So this is the perfect opportunity,
I'm very excited about this, to use the p5.js library
in this project.
So actually it's kind of strange this particular course,
this playlist of videos, isn't using p5.js,
because it's a thing I use basically everything
all over my channel.
But I wanted to take this opportunity
to take a little break from that and then
piece it back in where it can make the biggest contribution.
The p5.js Library was created by Lauren McCarthy
and is maintained by the Processing Foundation.
The Processing Foundation is a non-profit mission
to promote software literacy within the visual arts
and visual literacy within technology related fields
and to make those fields accessible
to diverse communities.
So I'm going to use that library to open up
a connection to the webcam to display the webcam's
image on an HTML5 JavaScript canvas,
and then to take the data from that image
and pass it to the database.
So this is another feature that I'm
going to add here in the client side JavaScript.
The client side JavaScript is doing the geolocation
and it is now going to call the p5 function Create
Video to create that video.
That video is going to be viewed in the client's browser.
But then when the Submit button is, the data from that image
will get sent to the server and stored into the database.
There are a variety of ways that I can use the p5.js library.
In fact, there's a whole p5.js online web
editor for making p5.js sketches right there in the browser.
But what I want to do here is integrate p5.js library
into this project that I'm building that involves node
and a bunch of other pieces that you've been
watching me do along the way.
So the way that I'm going to do that
is navigate over to the Getting Started page for p5.js.
I'm going to look for this link called p5.js CDN, or Content
Delivery Network.
A content delivery network is a hosting service
that will deliver you content.
And the content that I want is the p5.js library.
So I could click here and then I can grab--
you can see as of the time this writing the current version
is 0.8.0.
What I want to use is p5.min.js.
When you see a JavaScript library,
there's often what's known as a minified version
and a non-minified version.
So if I wanted to really peek in and read the source code
myself, I would get the bigger p5.js file.
But if I'm just using the library,
it's going to be a smaller file size
and make things kind of snappier.
So let me go and I can actually just go here under Copy,
and I can do Copy Script Tag is what I want.
And then if I come here into my HTML file,
I can go into the header.
And right above title I'm just going to paste it in.
That you give me the script tag for the p5.js library.
Now interestingly enough, you might
notice on this page there's a bunch of things listed.
There's like p5.dom, p5.sound, p5.dom.min.
Well I already covered the minified thing.
But the p5 library has several different components to it.
So the core library that you're pretty much always going
to want is just p5.min.js.
I also want to use the dom library.
That's where the functionality for using the webcam is.
And if I wanted to integrate-- there's
other functionality in there too but that's the functionality
I'm looking for.
If I wanted to have sound in my project
I could also look at the p5 sound library.
And I'll link to numerous p5.js tutorials
that I have on this channel in the video's description
if you want to check those out.
All right, so let me grab this.
Copy Script Tag, and there we go.
Before we get started with p5, I just
want to point out that I've added a little bit of code
since the last video.
Something very simple, but just to make it a bit more usable.
I added two links on the web page between this data entry
page, where I'm hitting submit and adding a latitude
longitude, and then the list page
which shows the things that are in the database.
I also changed these to paragraph elements
from divs so that there's a little line
break in between each.
So now I can go back and forth easily between these two pages
and also see the entries from the database with a little bit
of formatting.
Plenty still to do for you, a creative person
and possibly watching these videos,
thinking about how you want to design this yourself.
But a few small improvements so that I can work with this a bit
more easily in this particular tutorial.
Now I can finally write some p5.js code.
First thing that I'm going to want to add to my sketch
is a function called setup.
This is a little bit of an oddity about the way
that p5 works that's a little different than other JavaScript
libraries.
But p5 looks for a function called setup
in your global namespace, meaning it's just right there,
in this case in my script tag.
Setup is the equivalent of window on load or j queries'
ready function.
It's the function that gets executed
when everything-- when the web page is loaded
and everything is ready to go.
So one thing that I could do is I
could take all of this other stuff that I have--
why not-- and just put it in the setup function.
So let's make sure that adding the setup function,
adding the p5 library and adding the setup function still works.
So I'll go to the browser, and I'm just
going to refresh my page.
And it's taking a little while to get the latitude
and longitude.
There it got it.
You'll see that, whoa, there's this blank space there.
Why is there a blank space there?
Well, p5 will automatically add a canvas to your page.
So actually most of p5 is set up to draw.
So if I were to go to the end of setup
here and add background 255, 0, 0--
that's a red background-- and hit refresh,
you can see, oh, look there's a red canvas.
Now the truth is I don't actually
need a canvas for this project.
So I'm actually going to add a line of code called no canvas.
And then the thing that I do need
is I need that image from the webcam.
So I'm going to say const video = createCapture(Video).
And this just reminded me that I've made a mistake
and I said create video here, which is a p5 function.
That's for a local video file like a movie file
that you might load.
So actually what I want is create capture,
I'm capturing from the default video source
of the computer, the webcam.
Going back and refreshing the page.
First of all, it's asking me if I want to allow this web
application to use the camera.
And this is very important.
You can't just have a web page open up somebody's webcam
automatically.
This is a huge security issue.
And so there are lots of privacy and security questions
that you want to be thoughtful about when
building applications that access a user's webcam.
But here for what we're sort of tinkering around and learning
and practicing with I'm happy with just allowing it.
So I'm going to say Allow.
And you can see there it is, oh look.
You can see that I am in front of a green screen.
There's me.
Now it's quite large.
I don't need it to be that large on the page.
So I'm going to say-- this is part of p5 as well now--
video size, and let's just make it 320 by 240.
So now I have a smaller video image that's right there.
Perfect.
So what I want is when I hit Submit, I'm going to go--
I'm going to say happy--
I want that image to also get sent to the server.
How do I do that?
I'm realizing that the code would probably
flow a little nicer if I move this
to the beginning of the setup function.
Because ultimately what I want to do
is right here, when the user presses the button,
I'm grabbing the latitude longitude and mood
and posting that to the server.
So I want to add one more thing, which
is the data for the image.
Base64 encoding is a method to take some binary data--
in this case, the image, all the colors of the pixels
of the image--
and convert it to ASCII data, meaning a string of text.
This isn't doing anything to compress the image.
It's just repackaging the same data
in a format that's incredibly convenient to pass around.
In other words, I need to send the webcam image from here
to the server.
And a really easy way to do that is by sending a string of text
to the server.
If I can turn the image into a string of text then
I've got a nice way to post it to the server.
In JavaScript the HTML canvas API includes a function called
toDataURL(), which takes a canvas,
presumably with pixels of information in it,
and converts that to the base64 encoding of that image.
In p5, the video element has a canvas associated with it.
So I can say constant image = video.canvas.toDataURL().
So this is taking the video's canvas,
converting it to base64, and putting it
in this variable image.
And maybe what I'll call this, I'll
call this image 64 so I know that this
is the base64 encoding of the image.
The only thing is this won't actually work.
The video's canvas element is not there
by default. I need to alert p5 to the fact
that I want to use a canvas.
And to do that I say video.loadPixels.
This means take that video element,
load the pixels onto a canvas so that I can then
convert it to base64.
I can add that image then as a property to the data
that I'm posting.
I can then go to the server.
And if you recall, the post to the API of the server
just takes the body of that request, the post request,
and puts it right into the database.
So it's already done.
It should already be there.
Let's give this a try.
I'm going to refresh the page.
I had mango for breakfast this morning,
so I'm going to type in mango and give myself a big OK sign.
And that image, we can see it's there.
Look at all of this text that's in there.
This is the base64 encoding of that raw pixel data.
And now if I go to the database, I
can see that the latest entry has that base64 encoding.
Now we need to have a talk.
This perhaps isn't the best idea.
Do I really want to include all of the data
for the image in the database.
Is this going to be the most efficient way
to store this information?
Almost definitely not.
In fact, a more traditional strategy
might be to save that image data to a file
and then store the path to that file in the database itself.
But in terms of this quick and dirty prototyping
that I'm doing, this is a nice way to get started with this.
And I'll leave that as an exercise
to the viewer and something that I
will include as supplemental code with this video--
how to actually store this to a file on the server
and then the path in the database itself.
The only thing left for me to do now
is to add the image to the page that
lists all of the content from the database itself.
Now, I'm [INAUDIBLE] what's in the database.
You can see here this is the most recent entry.
And it includes the base64 image right there as a property
that it's reading from the database.
So this is actually--
I already have the template for doing this.
I just can head on over to the HTML, the JavaScript
code for creating all those dom elements
and I can make another one.
Like I can say image = document.createElement('img')
for image.
Then, unlike putting--
I'm not putting text content into that image.
Instead I want to put the base64 encoded data itself.
And I can do that with the source attribute.
So I can say image.src = image--
oh, no, sorry, equals, what is it?
item.image64.
So that's the base64 encoded data
in the database item in the image element source attribute.
And then add that to the page as well, right here, image.
And if I go back and refresh, we're getting errors.
We see oh look, there's that image there.
But we're getting errors because not all of the entries
have images associated with them.
So one way--
I could do some like error handling
and see if there is an image or not.
But let's actually just wipe the database clean and make
a few more entries and see if this works.
I'm going to and manually delete the database like this,
go back to the Enter page, and make a bunch of entries.
[MUSIC PLAYING]
All right, I made four entries.
There they are.
You can see that they're all entered in the database.
I can go to the code and see, like, look, here's
the database file.
Here's everything in there.
And you go over to list and see, here
are my entries into the database.
And there they are.
I now have the finished data selfie app.
This wraps up the data selfie app module.
I built the project now.
It's a crude prototype, but a working version of the idea.
So I'm going to add one more video.
I'm going to come back in a separate video
and kind of offer you some ideas, some exercise ideas,
of things that you might do to continue this.
But also I'm going to show you a few cleanup things
that I think are worthwhile.
For example, taking the JavaScript out of the HTML file
and putting it in a separate file, where you would create--
how you would create a CSS file if you
wanted to start thinking about layout and design
for your application.
It's beyond the scope of what I want to do in this series,
but I'll at least give you some pointers on how
to get started with that.
[MUSIC PLAYING]