 Hey everybody, this is Brian. Welcome to our 18th Flutter Tutorial. We're going to, hopefully today, wrap up our Dart conversation and then move into Flutter in the next tutorial. The reason why I want to do this one is it kind of goes through a overview of libraries and how to use them, which we've talked about a little bit, but not really in depth. So if you kind of just poke around Dart, you'll find that there is a pubdartlang.org. You get to it by going to libraries and then you can actually view the tutorial libraries, how to create packages, how to, you know, commonly use libraries, which I highly recommend you look at. But you'll see that pub is a tool for managing Dart packages, and we've talked about that before. And we've even talked about pubdartlang. When we go out there, you can search for just about anything. I mean, if you've thought about it, it's already out there, which is just nuts because Flutter itself is an alpha Dart spinout for a while, but just about anything you can think of. And back to the commonly used, you can see they've got a wrapper for Firebase, HTTP, internationalization, I can never say that right, logging. I mean, we've been over some of these before. So what I want to do today is really go over how to really integrate those into your project. We haven't really covered that. So if you're out there, you can search for HTTP or image. And I've got both pages up. Really, we're just going to work with these two. What we're going to do is we're going to download an image and actually resize it. And we're just going to show just how dead simple this is. In another language, this is a total nightmare of a project. Your boss as well, you know, we want to download this image and resize it. And you're thinking, I got to go find a image library. I got to figure out how to work with HTTP. I've got to, you know, do the get and the put and all that. No, it's dead simple. So let's just jump right into this. And we're going to make a console application in Dart. And we're going to call this downloader. All right, and this will load our project and load all the dependencies and calculate the meaning of life. Sometimes I really wonder what the hood with that thing. All right, so one thing we really haven't talked about is when you open a project, it opens these three files for you automatically. It opens this file, which is your code file out in your lib, this little guy. It opens the main file, which we've worked with many, many times, which is that guy, and then this pubspec.yaml. Notice how in yaml there is a dev dependencies. That's what we're really going to be working with here. So let's just kill that and we're going to get this and get that out of there. Now let's flip back to use anything that we find out in the Dart packages, like we just searched for HTTP. You can see that's how I got to it right there. Once you get to the page, you can do the readme file. You can see who the author is. The HTTP package was actually done by the Dart team itself and it's got some example code on how to use it. Now not all of these are created equal, meaning you'll find packages that have just absolutely zero documentation. So in that case, you would reach out to the author and say, hey, how do I use this thing? This is pretty straightforward and it works with streams. So under the hood, there's a lot going on, but to use it, it's dead simple. What you always want to look at is how to install it. Depend on it. So you open the dependencies, I'm sorry, you open the YAML file, copy this little bit here and then put it in the dependencies. So we're going to do that and we're going to do the same thing with image. We're going to go to installing, going to grab this and we're just going to put that in there. So save that YAML file. There are really two ways of doing this, but the easy way is just flip over to main.dart and you can see how, hey, pubspec has been edited. This file right here that we just did, what do you want to do? Do you want to upgrade, get, ignore? Well we want to get because we don't actually have those yet. You can see there's our pub file or pub folder right here. The little dot denotes that it's a hidden folder. So we're going to get dependencies and that may take a second depending on your download speeds. All right, once we're done, you should see that the little indicator has gone away and if we run through here, I think we may actually see them. Yep, there's HTTP right there. I'm not seeing an image. I'm wondering where that went. Hmm, maybe I'm wrong, but I'm pretty sure that's where it is. That's 11, 316. There it is. Oh, there it is right here. Image, doop. Now I feel very stupid. So that's where they end up going is under external libraries and they get bundled with your Dart package here. So we're going to kill that, go in here. Now we want to actually use these things, right? So many times it's very simple, very easily documented. It's right under here. They tell you how to do a pub get. You can do a flutter packages get. This is all command line work that we didn't have to do and then you can import it right here just by copying and pasting. So we're going to copy that for the image. Go back out here and we're going to copy that for our HTTP. Now if you have no idea what HTTP is, it's hypertext transfer protocol. It's basically how you communicate on the web. When you open a browser and you go to web page, it's actually talking a language called HTTP. It's a protocol. So we also want Dart.io. We need to set a few things up here. So what we're going to do is we're going to say void, download. The premise here being that we are going to download something and we are going to resize it. So what we need to do is actually set up our variables. String URL and because I just am dead lazy and I do not want to type that whole thing out, bam, we're just going to do this. If you're wondering what it is, it's just the hot reload gif, this guy. So we're going to download this and resize it and then we're going to say, all right, so now I need a file name. Let's just grab this, see where I'm at on my virtual machine here. I probably shouldn't know where that was, but so we got the directory and we're just going to say test.gif and then we're going to say preview.gif. So we've got our variable set up. Now we're just going to simply call the function. Yeah, see if we would have named that the path instead of file, it would have just done it for us automatically. All right, so a lot of typing so far, not really. Let's actually make the magic happen as they say. So we're going to say, yeah, I missed a step, that's why that's not working. We want to do this as HTTP. So if you're wondering what I'm doing here is we want to use the image package, but we don't want to import it as a variable. We just want to actually use it. Whereas the HTTP package, we want to actually import this and create a variable. I'm just kind of showing two different ways of doing this here. That way we can just call HTTP. And bang, we've got an instance of that variable already. We're going to say read bytes. And you notice how we've got some parameters here and it looks really nasty and ugly but really you don't have to mess with that too much. We're just going to say the url which is our variable. So it's going to take that url, go out there, and it's going to do the HTTP protocol in the background. It's going to read it as bytes and it's going to return a variable we're calling data. And when, yeah, blah. Then we need to do a then on the data itself. What's really going on here is, well, you guessed it. We're working with an asynchronous function so that didn't work as planned. There we go. Kind of. That's a little better. Those always trip me up. I'm still not used to those for whatever reason. They just mess me all up. So what we've got so far is we're going out, we're reading the url as a byte stream, and then once it's done we've got the data itself. I probably shouldn't call that data. Let's call this, what should we call this? F data. Why not? That way it's not super confusing what we're doing here. Then we're going to say file f equal new file from path. So then once we actually have the file we're going to, or once we have the data we're going to open a file and we are going to actually dump that data down to the desk and we're going to say random access file and we've done this before as far as opening the file. And what we want to do here is we want to open sync because we don't want to mess around with any of the asynchronous stuff just because I'm being a little lazy this morning. And we want to just write to that file. And here we want to do what's called write from sync. And you notice how it's taking a templated list using ints. Now really what that is is that is our actual byte stream. So we're going to do that and we're going to say fdata. Actually we could just call that buffer probably easier. Why didn't I think of that? Genius. Man these Dart developers are just awesome. Alright so then we're going to flush sync and then we're going to close sync. That way we've got our synchronous code in there. We don't have to worry about any weird timing issues that are going to pop up due to any synchronous calls. Then we want to actually resize the image. So let's actually, let's put some commenting in here. Alright so now that we've actually got the file down to the disk what we want to do is we want to actually resize it. And here we're going to use the image library. So there's image. I should call image library image package. I think the two terms are kind of interchangeable. And we want to actually decode image. And we could actually take that buffer. You see how it is a list int. But what I want to do is I want to actually grab the file. So we're going to say new file. And we want read as bytes sync. So really we're just going to say hey image. Decode the image. I mean it's going to read in the raw bytes. And then it's going to decode that because every image has a certain codec. It's not really a codec. It's called an encoding. You know the difference between a bitmap or a gif or jpeg or something like that is the encoding that it actually uses. So it's going to decode that image by using the bytes that we're reading from the actual file on the disk. Sound confusing. Now you know why this tutorial gets a little nuts in other languages. All right so now that we've actually got the image in memory we want to actually resize it. Actually I should say load the image. Now we're going to resize the image. All right so we're going to say image thumbnail. And we want to copy resize. And we're going to take the actual image. And we want this to be 200 pixels. Then once we're done we want to save the thumbnail out to the disk. So we're going to say and we want to do write bytes as sync. And we want to actually do this as a png not a gif because why not. But you can see how you can decode as a gif gif animation jpeg tga. You can do a name damage type things like that. So there's a lot of power in this little little package here. So we're going to encode this as a png. All right so that is a lot of typing. Let's see if this actually works. You notice how right now we've got absolutely nothing out in our folder except for a few other folders and the video that I'm currently recording. We're going to download that file and encode it. You can see process finished exit code zero. And you can see how there is our test. Oh yeah that is not a gif file that's why let's rename that to a png. Okay just simply because I had the name wrong there is our encoded here to kind of solidify that this actually does work. We're going to delete all this nonsense and we're going to actually fix this because remember in the very end I changed it to a png instead of a gif. So what we're doing is we're downloading the gif putting it on the disk and then we're changing the size and changing the encoding. Sorry I kind of confused you a little bit but I wanted to do both just to show that it could. And Dennis is just gonna work. Nothing up my sleeve ladies and gentlemen and bam you can see it's actually writing it out to disk and when it's done which it is you can see here is the full-sized. That's not working for some reason. It is there trust me there is our thumbnail. I wonder why this one isn't working. Hmm I'll have to figure that out. Oh there it goes. I was just impatient it was still loading. So you notice how this is animated whereas the actual preview is not animated. That is part of due to the part in part due to the encoding which is right here encode png. So let's see if we can go encode and I'm not sure how that works but you could do encode gif animation and then you would have to do the animation part. I'm not sure how to do that to be brutally honest it's kind of out of the scope of this tutorial but I just wanted you to be aware that that could happen. So that is a pretty complex little application in a very small package. I'm really impressed by how dark packages work and how everything just kind of fits together and I wanted to kind of do this tutorial before we you know just head first into Flutter to show that you can get this level of complexity in a very small simple to easy to use package. So if it seemed a little bit confusing it's because it's kind of a confusing topic and there's a lot of information that we're skipping over like we haven't really touched on encoding and decoding we haven't touched on HTTP get and put and delete and all that stuff. We also really didn't talk a whole lot about the real under the hood differences between these image formats but you can see now how to actually download a file off the internet and then work with it using the image package. A lot of talking I think I'm spent that's all for this tutorial I hope you found this educational and entertaining and thank you for watching. Oh and be sure to visit my website void realms.com for the source code for this and other tutorials.