I am currently playing around with golang and Martini and such and wanted to dynamically serve some manipulated/generated images. Here's a minimal example:
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()
}
That compiles fine, but instead of serving an image, I get some "Content-Type:text/plain; charset=utf-8" that looks like this:
<*image.RGBA64 Value>
I am pretty sure that I need to encode the image again and then serve it. But im not quite sure how to do this without saving the image to the disk...
Thanks in advance!
You can write to the ResponseWriter directly because it implements the io.Writer interface, no need to use a buffer or copy the image to disk.
You were almost there, just needed to set the content type and like you mentioned encode the image.Image object back into a jpeg. Luckily, the jpeg.Encode() method needed a writer to write to and you have the ResponseWriter available at your disposal to do just that thanks to Martini having the ability to inject it into your handler.
Note: you will probably want to do a more robust job of error handling than I have provided. This is just to get the ball rolling. ;)
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()
}