3

私は現在、golang や Martini などで遊んでおり、操作/生成された画像を動的に提供したいと考えていました。最小限の例を次に示します。

package main

import (
    "github.com/codegangsta/martini"
    "github.com/nfnt/resize"
    "image"
    "image/jpeg"
    "log"
    "os"
)

func thumb() image.Image {
    file, err := os.Open("test.jpg")
    if err != nil {
        log.Fatal(err)
    }

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

    m := resize.Resize(0, 200, img, resize.MitchellNetravali)

    return m
}

func main() {
    m := martini.Classic()
    m.Get("/") image.Image {
        return thumb()
    })
    m.Run()
}

これは正常にコンパイルされますが、画像を提供する代わりに、次のような「Content-Type:text/plain; charset=utf-8」が得られます。

<*image.RGBA64 Value>

画像を再度エンコードしてから提供する必要があると確信しています。しかし、イメージをディスクに保存せずにこれを行う方法がよくわかりません...

前もって感謝します!

4

1 に答える 1

7

ResponseWriter は io.Writer インターフェイスを実装しているため、直接書き込むことができます。バッファを使用したり、イメージをディスクにコピーしたりする必要はありません。

コンテンツタイプを設定する必要があり、前述のように image.Image オブジェクトを jpeg にエンコードする必要がありました。幸いなことに、jpeg.Encode() メソッドには書き込み先のライターが必要でしたが、Martini にはハンドラーに挿入する機能があるため、ResponseWriter を自由に使用できます。

注: おそらく、私が提供したよりも堅牢なエラー処理の仕事をしたいと思うでしょう。これは単にボールを転がすためです。;)

package main

import (
    "image"
    "image/jpeg"
    "log"
    "net/http"
    "os"

    "github.com/codegangsta/martini"
    "github.com/nfnt/resize"
)

func thumb() image.Image {
    file, err := os.Open("test.jpg")
    if err != nil {
        log.Fatal(err)
    }

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

    m := resize.Resize(0, 200, img, resize.MitchellNetravali)

    return m
}

func main() {
    m := martini.Classic()

    m.Get("/", func(res http.ResponseWriter, req *http.Request) {
        res.Header().Set("Content-Type", "image/jpeg")
        err := jpeg.Encode(res, thumb(), &jpeg.Options{100})
        if err != nil {
            res.WriteHeader(500)
        } else {
            res.WriteHeader(200)
        }
    })
    m.Run()
}
于 2014-03-21T18:06:26.403 に答える