imagegogif

having trouble when implementing the interface 'Quantizer' and 'Drawer' of GIF


In image/draw, Quantizer and Drawer are defined like this:

type Quantizer interface { 
    Quantize(p color.Palette, m image.Image) color.Palette 
}
type Drawer interface {
    Draw(dst Image, r image.Rectangle, src image.Image, sp image.Point)
}

And there are codes in gif.Encode(w io.Writer, m image.Image, o *Options) like this:

if opts.Quantizer != nil { 
    pm.Palette = opts.Quantizer.Quantize(make(color.Palette, 0, opts.NumColors), m) 
} 
opts.Drawer.Draw(pm, b, m, b.Min)

When I want to write an image quantization algorithm myself, I need to implement draw.Quantizer and draw.Drawer.

As you see, opts.Quantizer.Quantize returns the Palette. But actually, when calling opts.Drawer.Draw, I need not only the Palette, but also some other data from Quantize.

Is it possible to make the quantization data able to be used?


Edited on 25 Dec.

For example, I get an indexing map when quantize. When I draw, I need this indexing map to make my algorithm faster. What can I do to pass this indexing map into the Drawer?


Solution

  • type quantizer struct {
        indexingMap *IndexingMap
    }
    func (q *quantizer) Quantize(p color.Palette, img image.Image) color.Palette {
        // do sth
        // q.indexingMap = sth
    }
    type drawer struct {
        q *quantizer
    }
    func (d drawer) Draw(dstOri draw.Image, rect image.Rectangle, src image.Image, sp image.Point) {
        // do sth with d.q.indexingMap
    }
    func Opt() *gif.Options {
        q := &quantizer{}
        return &gif.Options{
            NumColors: 256,
            Quantizer: q,
            Drawer:    drawer{q: q},
        }
    }
    

    Then I can use these quantization data in Draw method.