2014-11-04 151 views
3

我在不存在的情况下动态创建图像。 IE example_t500.jpg当被要求时将从example.jpg创建。我遇到的问题是在显示丢失图像之前请求显示创建的图像。刚刚创建的Go服务图像

代码:

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

这是我第一次尝试使用Go时遇到了问题渲染图像。任何帮助表示赞赏。

回答

5

您需要做几件事情。

首先,你需要从WebHandler功能删除此行:

http.Handle("/", http.FileServer(http.Dir("example_t500.jpg"))) 

这就是设置默认服务MUX处理的根路径 - 但你已经这样做,在你的main功能在这里:

http.HandleFunc("/", WebHandler) 

所以,每次你点击根路线,你实际上只是告诉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) 
} 

那就是手动版本。还有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 
} 

接受的方法中形成io.Writer ..然后它编码了这一点。然后你可以这样称呼你的方法:

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 
} 
+0

这个效果很好。有没有一种方法可以在不实际创建的情况下渲染调整大小的图像? – 2014-11-04 21:38:34

+1

当然..让我更新我的答案,包括这一点。 – 2014-11-04 21:40:10

+1

答复已更新。 – 2014-11-04 21:43:56