Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

Save an image from url to file

Tags:

go

Very new to Go (first simple project I'm working on).

Question: How do I get an image from URL and then save it to my computer?

Here's what I have so far:

package main  import ( "fmt" "net/http" "image" "io/ioutil" )  func main() {         url := "http://i.imgur.com/m1UIjW1.jpg"         // don't worry about errors     response, _ := http.Get(url);      defer response.Body.Close()     m, _, err := image.Decode(response.Body)      error := ioutil.WriteFile("/images/asdf.jpg", m, 0644) } 

However, when I run this code, I get cannot use m (type image.Image) as type []byte in function argument

I'm assuming I have to convert image.Image (variable m) into an undefined amount of bytes? Is that the correct way to go about this?

like image 267
Jacob Kranz Avatar asked Mar 14 '14 22:03

Jacob Kranz


People also ask

How do I create a URL for an image?

How to create a URL for an image using Imgur. By far one of the easiest image-to-URL converters on the market. Go to the Imgur website, then on the top left click the 'New post' button. Then you can drag an image into the box or you can select the image from your desktop or another source.

How can I download image from URL in PHP?

file_put_contents ( $img , file_get_contents ( $url )); echo "File downloaded!" File downloaded! Note: It save the image to the server with given name logo.


2 Answers

There is no need to decode the file. Simply copy the response body to a file you've opened. Here's the deal in the modified example:

  1. response.Body is a stream of data, and implements the Reader interface - meaning you can sequentially call Read on it, as if it was an open file.
  2. The file I'm opening here implements the Writer interface. This is the opposite - it's a stream you can call Write on.
  3. io.Copy "patches" a reader and a writer, consumes the reader stream and writes its contents to a Writer.

This is one of my favorite things about go - implicit interfaces. You don't have to declare you're implementing an interface, you just have to implement it to be used in some context. This allows mixing and matching of code that doesn't need to know about other code it's interacting with.

package main

import (     "fmt"     "io"     "log"     "net/http"     "os" )  func main() {     url := "http://i.imgur.com/m1UIjW1.jpg"     // don't worry about errors     response, e := http.Get(url)     if e != nil {         log.Fatal(e)     }     defer response.Body.Close()      //open a file for writing     file, err := os.Create("/tmp/asdf.jpg")     if err != nil {         log.Fatal(err)     }     defer file.Close()      // Use io.Copy to just dump the response body to the file. This supports huge files     _, err = io.Copy(file, response.Body)     if err != nil {         log.Fatal(err)     }     fmt.Println("Success!") } 
like image 54
Not_a_Golfer Avatar answered Sep 28 '22 07:09

Not_a_Golfer


package main  import (     "io"     "net/http"     "os"     "fmt" )  func main() {     img, _ := os.Create("image.jpg")     defer img.Close()      resp, _ := http.Get("http://i.imgur.com/Dz2r9lk.jpg")     defer resp.Body.Close()      b, _ := io.Copy(img, resp.Body)     fmt.Println("File size: ", b) } 
like image 39
Cory Avatar answered Sep 28 '22 09:09

Cory