将图像从url保存到文件

时间:2014-03-14 22:59:21

标签: go

Go的新手(我正在做的第一个简单项目)。

问题:如何从URL获取图像然后将其保存到我的计算机中?

这是我到目前为止所拥有的:

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)
}

但是,当我运行此代码时,我得到cannot use m (type image.Image) as type []byte in function argument

我假设我必须将image.Image(变量m)转换为未定义的字节数量?这是正确的方法吗?

4 个答案:

答案 0 :(得分:32)

无需解码文件。只需将响应正文复制到您打开的文件即可。以下是修改示例中的交易:

  1. response.Body是一个数据流,实现了Reader接口 - 这意味着您可以在其上顺序调用Read,就像它是一个打开的文件一样。
  2. 我在这里打开的文件实现了Writer接口。这是相反的 - 它是您可以调用Write的流。
  3. io.Copy“补丁”读者和作者,使用读者流并将其内容写入Writer。
  4. 这是我最喜欢的关于go - 隐式接口的事情之一。您不必声明您正在实现接口,您只需实现它以在某些上下文中使用。这允许混合和匹配不需要知道与其交互的其他代码的代码。

    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!")
    }
    

答案 1 :(得分:2)

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)
}

答案 2 :(得分:0)

response.Body的类型是什么?您应该将其转换为[]byte(如果不是)并将其写入磁盘。除非您有理由将数据视为图像,否则没有理由使用image类。只需将数据视为一系列字节并将其写入磁盘即可。

答案 3 :(得分:0)

您也可以使用 ReadFrom 方法:

package main

import (
   "net/http"
   "os"
)

func main() {
   r, e := http.Get("https://i.imgur.com/m1UIjW1.jpg")
   if e != nil {
      panic(e)
   }
   defer r.Body.Close()
   f, e := os.Create("m1UIjW1.jpg")
   if e != nil {
      panic(e)
   }
   defer f.Close()
   f.ReadFrom(r.Body)
}

https://golang.org/pkg/os#File.ReadFrom