Q:

Serve a decoded image via Martini

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!

A:

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

