If you know upfront the bytes you need to add in the stream (whatever the stream, image or not), building a Writer object for this specific purpose is not really hard.
Here is an example:
package main
import (
"fmt"
"image"
"image/draw"
"image/jpeg"
"image/color"
"os"
"io"
)
type ByteInserter struct {
n int
b []byte
pos int
w io.Writer
}
func NewByteInserter(w io.Writer) *ByteInserter {
return &ByteInserter{w:w}
}
func (bi* ByteInserter) Set( b[]byte, pos int ) {
bi.b = b
bi.pos = pos
}
func (bi *ByteInserter) Write( p []byte ) (n int, err error) {
if bi.n>bi.pos || bi.n+len(p)<=bi.pos {
n, err = bi.w.Write(p)
bi.n += n
} else {
cut := bi.pos-bi.n
if cut > 0 {
n,err = bi.w.Write(p[:cut])
bi.n += n
if err != nil {
return
}
}
_,err = bi.w.Write(bi.b)
if err != nil {
return
}
n2 := 0
n2, err = bi.w.Write(p[cut:])
bi.n += n2
n += n2
}
return
}
func main() {
// Blue rectangle, stolen from Nigel Tao's post
// http://blog.golang.org/go-imagedraw-package
img := image.NewRGBA(image.Rect(0, 0, 640, 480))
blue := color.RGBA{0, 0, 255, 255}
draw.Draw(img, img.Bounds(), &image.Uniform{blue}, image.ZP, draw.Src)
file, err := os.Create("file.jpg")
if err != nil {
panic(err)
}
bi := NewByteInserter(file)
bi.Set( []byte("XXX"), 2 ) // Three bytes added at position 2
jpeg.Encode(bi,img,nil)
file.Close()
fmt.Println("Written!")
}
That said, editing a stream to customize an image seems really hackish to me.