在刚刚创建的Go中提供图像

Aus*_*nro 6 image go

当一个图像不存在时,我会动态创建一个图像.请求时,IE example_t500.jpg将从example.jpg创建.我遇到的问题是在显示丢失图像之前请求显示创建的图像.

码:

package main

import (
        "image/jpeg"
        "net/http"
        "log"
        "os"
        "strings"
        "fmt"
        "strconv"
        resizer "github.com/nfnt/resize"
    )

func WebHandler (w http.ResponseWriter, r *http.Request) {
    var Path = "../../static/img/photos/2014/11/4/test.jpg"
    ResizeImage(Path, 500)
    http.Handle("/", http.FileServer(http.Dir("example_t500.jpg")))
}

func ResizeImage (Path string, Width uint) {
    var ImageExtension = strings.Split(Path, ".jpg")
    var ImageNum       = strings.Split(ImageExtension[0], "/")
    var ImageName      = ImageNum[len(ImageNum)-1]
    fmt.Println(ImageName)
    file, err := os.Open(Path)
    if err != nil {
        log.Fatal(err)
    }

    img, err := jpeg.Decode(file)
    if err != nil {
        log.Fatal(err)
    }
    file.Close()

    m := resizer.Resize(Width, 0, img, resizer.Lanczos3)

    out, err := os.Create(ImageName + "_t" + strconv.Itoa(int(Width)) + ".jpg")
    if err != nil {
        log.Fatal(err)
    }
    defer out.Close()

    jpeg.Encode(out, m, nil)
}

func main() {
    http.HandleFunc("/", WebHandler)
    http.ListenAndServe(":8080", nil)
}
Run Code Online (Sandbox Code Playgroud)

这是我第一次尝试使用Go并且无法渲染图像.任何帮助表示赞赏.

Sim*_*ead 14

您需要做一些事情.

首先,您需要从WebHandler函数中删除此行:

http.Handle("/", http.FileServer(http.Dir("example_t500.jpg")))
Run Code Online (Sandbox Code Playgroud)

这是设置默认的服务多路复用器来处理根路由 - 但是你已经在你的main函数中完成了这个:

http.HandleFunc("/", WebHandler)
Run Code Online (Sandbox Code Playgroud)

因此,每当你点击根路线时,你实际上只是告诉servemux再次处理它......但不同.

你想要做什么..设置Content-Type响应的标题..然后将文件的内容复制到响应流.像这样的东西:

func WebHandler (w http.ResponseWriter, r *http.Request) {
    var Path = "../../static/img/photos/2014/11/4/test.jpg"
    ResizeImage(Path, 500)

    img, err := os.Open("example_t500.jpg")
    if err != nil {
        log.Fatal(err) // perhaps handle this nicer
    }
    defer img.Close()
    w.Header().Set("Content-Type", "image/jpeg") // <-- set the content-type header
    io.Copy(w, img)
}
Run Code Online (Sandbox Code Playgroud)

那是手动版.还有http.ServeFile.

编辑:

响应您的评论 - 如果您根本不想编写文件并且只是动态地提供它,那么您需要做的就是将其传递http.ResponseWriterEncode方法.jpeg.Encode采取io.Writer..就像io.Copy在我原来的例子中一样:

// Pass in the ResponseWriter
func ResizeImage (w io.Writer, Path string, Width uint) {
    var ImageExtension = strings.Split(Path, ".jpg")
    var ImageNum       = strings.Split(ImageExtension[0], "/")
    var ImageName      = ImageNum[len(ImageNum)-1]
    fmt.Println(ImageName)
    file, err := os.Open(Path)
    if err != nil {
        log.Fatal(err)
    }

    img, err := jpeg.Decode(file)
    if err != nil {
        log.Fatal(err)
    }
    file.Close()

    m := resizer.Resize(Width, 0, img, resizer.Lanczos3)

    // Don't write the file..
    /*out, err := os.Create(ImageName + "_t" + strconv.Itoa(int(Width)) + ".jpg")
    if err != nil {
        log.Fatal(err)
    }
    defer out.Close()*/

    jpeg.Encode(w, m, nil) // Write to the ResponseWriter
}
Run Code Online (Sandbox Code Playgroud)

接受io.Writer方法中的a ..然后将其编码为.然后,您可以像这样调用您的方法:

func WebHandler (w http.ResponseWriter, r *http.Request) {
    var Path = "../../static/img/photos/2014/11/4/test.jpg"
    ResizeImage(w, Path, 500) // pass the ResponseWriter in
}
Run Code Online (Sandbox Code Playgroud)

  • 当然..让我更新我的回答,包括那个. (2认同)