2014-11-04 150 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