Uploading an Image - Developer Diary #Day1
Skills:
AI Pair Programming60%
Key Takeaways
Demonstrates how to build a camera app, focusing on progressively enhancing image capture and upload
Full Transcript
hey everyone its Matt again I'm here to talk a little bit more about the app that I've been building we'd already know about the app you can watch an introduction in the previous video and there's a link in the description now this is a camera app and direct access to the camera is a pretty new feature that's available in modern browsers but not so much in older browsers and not for people who don't even have a camera for example people they're on desktops so how do we progressively enhance capturing an image or one of the easiest things we could do is take a URL of an image that it's actually hosted elsewhere on the web and just fetch that so if we're taking an image from a URL the code for that is dead simple we just need some input to take the URL and then some sort of action in this case a button say that we'd like to actually go for the URL and then we just set the source of an image to be whatever the user typed in so I have a test image URL here I base it in like they go and my image is in the page this is a very very simple way of doing this it does have a couple of problems though the big one being that if the server that the image is hosted on doesn't support cause headers or doesn't send the right cause headers then you won't actually be able to edit this image you're still be able to display it in the page but we're making a photo editing app essentially so we need to be able to get at those pixels and transform them in some way and without cause that's just not going to happen you can get around that by using a proxy server so you run your own server and you fetch all URLs through that so you make your request to your server with the URL and then the server goes away and makes the request to the real server and in the the and then the image comes back through that chain but that's a little there's a little bit excessive for what we want to do here you have to run your own server which can handle the traffic of all of your users for something you really only want to be doing inside the browser so how can we improve on using URL provided by the user well we could use a file input and let the user just upload the photo directly to us so it's an input of type file which tells the browser that it should prompt the user to give us a file and traditionally this was so that that file could be uploaded to your server as part of a form but in modern browsers we can take the file from the input and use it in the client without actually sending it to the server now we can enhance this again first enhancement is to say that we accept images so here we use the accept attribute and we pass in a mime type or in this case a wild-card mime type we say image slash start say we want the user to give us an image so the browser can then prompt the user with a file input that only gives them images so if we see here when we open this up this is showing me only the images that are on my desktop now the file input has a change event which we can listen to and anytime that the user changes what is selected in that file input this event will get triggered and here I'm just login to the console what the output of that is the the the files object of our input so here in our handler I'm taking a target which is the target of the event which is actually going to be the file input and we're looking at this files property and for a moment I'm just cutting that out at the console and you can see that it is a file list and we'll learn more all about file lists later on you're the good thing about the accept attribute is that it lets mobile browser browsers know that they could send us a photo straight from the camera if they wanted to so when they pop up the chooser as well as offering the ability to upload a file they also give the opportunity to say would you like to take a photo from the camera this will go straight to the native camera app and allow the user to take photo there and then which can then get passed into your app which is brilliant this is almost what we want for our own app there is a final possibility for this which is we can add an we can add in a natural record capture so we add in capture here and by default the if you just put in capture that says that I'd like to go to the camera directly so on a mobile browser this will pop up the native camera app without offering the chooser first which if you really only want photos straight from a camera is perfect you skip a step but there's a little bit of a problem here you can't feature detect where the capture is going to do this and this means that on desktop browsers you only going to prompt for a file because that's what the file input does whereas on mobile browsers you're only going to prompt for images from the camera it's not an equal thing between the two and what if a user on mobile wants to upload a file that's on their SD card for example if you are going to use the capture attribute there is actually a couple of extra things you can do is that you can set it to one of two values to say which camera you'd prefer so you can set it to be a user which says that you want the camera that is facing the user so this is your selfie camera or you can set it to be capture equals environment which says you want the camera that faces the environment ie the normal camera that faces away from the user if the device happens to only have one camera it will still give you the camera that it does have and this just sets a preference so the accept header and the capture attribute give us a couple of ways to enhance the experience for mobile users so let's look at some ways we can enhance things for desktop users as well one thing that's fairly common to do on desktop that you wouldn't do a mobile is drag and drop and that's supported by the web as well so here we set up a target to be dropped onto the target is just a development it could be pretty much any element you like and we set up this drop event listener so that when something is dropped onto the element what should we do well we should stop propagation because we're actually handling it in our element here and we should prevent the default - if I drag this image just into the browser not onto the element it just loads the image into the tab and is no longer on our page and we don't want that to happen so that as soon as we drop it onto our element we get the event fired but then it navigates the image so we prevent the default behavior as well here again just logging out the results of this the event here is a drag event which has a data transfer object game we'll talk about that and that has a files property which is again a files file list so if I drag this onto the element we can see down here that we get the file list object now I have another event listener down here for drag over and this says what should happen as you're dragging as you're dragging this over the element what should the behavior be and here we're saying that we want the effect to be a copy so that when the drag finishes when that drop happens we are copying the information from the image into the event and again we need stop propagation and prevent the default to stop the normal browser things happening when we drag that over and it is the setting the drug draw a perfect copy which gives us this plus icon on the mouse lastly another desktop feature is the clipboard API that allows us to copy an image from somewhere from the file system or from another application and just paste it straight into the app now in chrome you can paste an image or any file into any element on the page you could set the event listener for the pasted event on the document and that would work fine but not all browsers support this the same way and Microsoft edge for example requires that the element be is both selectable and editable so here I've got a text area which I can paste into and you can see immediately there's a slight UX problem here we're not asking the user to type anything in but we've given them a text input so this makes it slightly awkward to let users know what they should be doing in your app you can if you want take an editable element put it off screen and then when someone clicks onto an element there is on screen but not editable you actually set the focus manually in your code to be the editable element when the user pastes it goes to the element that you want but then you run into some accessibility issues and it's just slightly awkward for that reason I'm not going to add paste into my own camera app but I just wanted to let you know the option was there so how do we actually handle the paste event very easy we take whatever element that we're going to use in this case it's our text area and we add an event listener for the paste event and when that event gets handled we get the event has a clipboard data property with a files property inside it and that files property as we can see is yet again another file list and it's just sure that this really works and copy the image and I paste it in and after ammo because this is a big file and it is doing a copy we get a new entry in a console with the filing and you can see that we get the the name and modify day and things like that so that brings us to the question of what is a file list object what is this thing that we've been getting we've been getting it from the file input we got it from drag and drop and then we got it from the clipboard API so a file list is kind of like an array it's an object with numeric keys which with each property being a file object as I say it's array like you doesn't have any of the array methods like for each or map but you can create an array by using a raid art from so I could I could say my array is a raid up from file list in this case though because it's numeric keys I can still use a normal for loop every so that's what I'm going to do here as I say the entries in this in this file list our file objects now file object is actually exactly the same as a blob so if you've used a blob before you know exactly how to use this the only difference is that a file object if we look over here has a couple of extra properties has the last modified and it has the name things that are file type information that you wouldn't have on the blob and this means you can use it however you would use a blob blobs can be stored in index DB you can get a URL from them which means that you can use that URL as the source of an image you can pass them around to workers and things because they are stripped cloneable you can do a lot of things with the blob in this case I'm going to take the very first file that matches whose type is an image and I will and I'll just set the source of my output image to be whatever their images so this is a drag-and-drop and you can see it sets the source image to a URL has been created from that blob so that's how we're getting an image when we don't have direct access to the camera which gives us a great progressive enhancement story some good places to fall back to but for accessing the camera directly we'll talk about that next time so join me then and thank you for watching thanks for watching if you like to see more of our videos click here and I see you again Cheers
Original Description
In this Developer Diary series, Mat Scales is talking you through how to build a camera app. Today Mat looks at how to 'progressively enhance capturing an image' and how to upload that image to your app.
Next episode to be released on 25th October!
Previous episode, "Creating a Camera App": https://goo.gl/8nQ1TH
Check out the code here: https://goo.gl/Kvrsor
Watch the rest of the series here: https://goo.gl/vZQtLZ
Subscribe to the Chrome Developers channel for the latest videos here: http://goo.gl/LLLNvf
Watch on YouTube ↗
(saves to browser)
Sign in to unlock AI tutor explanation · ⚡30
Playlist
Uploads from Chrome for Developers · Chrome for Developers · 0 of 60
← Previous
Next →
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
Polymer Performance Patterns (The Polymer Summit 2015)
Chrome for Developers
Polymer Power Tools (The Polymer Summit 2015)
Chrome for Developers
Chrome Dev Summit 2014 – Chrome Case Studies
Chrome for Developers
Web Directions Code 2015 round up
Chrome for Developers
Maintainable Code - HTTP203
Chrome for Developers
iron-ajax… wat?! -- Polycasts #26
Chrome for Developers
The Guardian - Supercharged
Chrome for Developers
ES2015 (next version of JavaScript), Totally Tooling Tips (S2 Ep1)
Chrome for Developers
#AskPolymer: Rob answers all the questions ever -- Polycasts #27
Chrome for Developers
The Future of JavaScript - HTTP203
Chrome for Developers
Data Binding 101 -- Polycasts #28
Chrome for Developers
The Guardian part 2 - Supercharged
Chrome for Developers
The Future of Web Audio: with Chris Wilson and Chris Lowis
Chrome for Developers
Chrome 46: New motion-path animations, client hints and service worker improvements
Chrome for Developers
Sublime Snippets, Totally Tooling Tips (S2 Ep2)
Chrome for Developers
#AskPolymer: How do you make the show? -- Polycasts #29
Chrome for Developers
Critical Path CSS, Totally Tooling Tips (S2 Mini Tip #1)
Chrome for Developers
Binding to Objects -- Polycasts #30
Chrome for Developers
Player FM - Supercharged
Chrome for Developers
Where’s the Designer? #AskPolymer -- Polycasts #31
Chrome for Developers
Jake Beats Wikipedia - HTTP203
Chrome for Developers
Supercharged Observers! -- Polycasts #32
Chrome for Developers
Jai's Web blog - Supercharged
Chrome for Developers
Windows Command-line Tooling, Totally Tooling Tips (S2, Ep4)
Chrome for Developers
What about internationalization? #AskPolymer -- Polycasts #33
Chrome for Developers
Developing for Billions (Chrome Dev Summit 2015)
Chrome for Developers
Google+ Performance Improvement Comparison
Chrome for Developers
Deploying HTTPS: The Green Lock and Beyond (Chrome Dev Summit 2015)
Chrome for Developers
Progressive Web Apps (Chrome Dev Summit 2015)
Chrome for Developers
Instant Loading with Service Workers (Chrome Dev Summit 2015)
Chrome for Developers
Increase Engagement with Web Push Notifications (Chrome Dev Summit 2015)
Chrome for Developers
Engaging with the Real World: Web Bluetooth and Physical Web (Chrome Dev Summit 2015)
Chrome for Developers
Asking for Permission: respectful, opinionated UI (Chrome Dev Summit 2015)
Chrome for Developers
Polymer - State of the Union (Chrome Dev Summit 2015)
Chrome for Developers
Building Progressive Web Apps with Polymer (Chrome Dev Summit 2015)
Chrome for Developers
Introduction to RAIL (Chrome Dev Summit 2015)
Chrome for Developers
DevTools in 2015: Authoring to the max (Chrome Dev Summit 2015)
Chrome for Developers
RAIL in the real world (Chrome Dev Summit 2015)
Chrome for Developers
#ChromeDevSummit talks are up - W00T! -- Polycast #34
Chrome for Developers
V8 Performance from the Driver's Seat (Chrome Dev Summit 2015)
Chrome for Developers
Quantify and improve real-world RAIL (Chrome Dev Summit 2015)
Chrome for Developers
Owning your performance: RAIL (Chrome Dev Summit 2015)
Chrome for Developers
HTTP/2 101 (Chrome Dev Summit 2015)
Chrome for Developers
Leadership Panel (Chrome Dev Summit 2015)
Chrome for Developers
Build Processes, Totally Tooling Tips (S2, Ep 5)
Chrome for Developers
Accessibility (Chrome Dev Summit 2015)
Chrome for Developers
Binding to Arrays -- Polycasts #35
Chrome for Developers
HTTP2 - HTTP203
Chrome for Developers
Chrome 47: Splash Screens, requestIdleCallback and better desktop notifications (New in Chrome)
Chrome for Developers
Call For Submissions - Supercharged
Chrome for Developers
Cross Device Testing, Totally Tooling Tips (S2 Ep6)
Chrome for Developers
Testing AJAX with Web Component Tester -- Polycasts #37
Chrome for Developers
Slack: Extended Xmas Special - Supercharged
Chrome for Developers
Browser testing with Travis & Sauce Labs -- Polycasts #38
Chrome for Developers
Optimize for production with Vulcanize -- Polycasts #39
Chrome for Developers
Highlights from Chrome Dev Summit 2015
Chrome for Developers
Chrome 48: Custom buttons in notifications, DevTools Security panel, and Presentation mode
Chrome for Developers
Crisper: Protecting your Polymer app with CSP -- Polycasts #40
Chrome for Developers
How do I use Sass with Polymer? #AskPolymer -- Polycasts #41
Chrome for Developers
Colors – DevTools Tonight #0 (Pilot)
Chrome for Developers
More on: AI Pair Programming
View skill →Related Reads
📰
📰
📰
📰
After shocking quarter, IBM insists that AI isn’t killing the mainframe
TechCrunch AI
Are AI labs pelicanmaxxing?
Simon Willison's Blog
Google justifies its massive AI spending with a booming cloud business
TechCrunch AI
The White House Is Trying to Figure Out What to Do About Chinese AI
Wired AI
🎓
Tutor Explanation
DeepCamp AI