always convert images to NRGBA

this type is rpc-serializable, and we avoid repeated color conversion
This commit is contained in:
Norwin Roosen 2020-02-14 12:39:16 +01:00
parent 3f06bf6b82
commit 2ec417da6a
6 changed files with 18 additions and 10 deletions

11
io.go
View File

@ -31,3 +31,14 @@ func writeImage(path string, img image.Image) {
log.Fatal(err) log.Fatal(err)
} }
} }
func imgToNRGBA(img image.Image) *image.NRGBA {
b := img.Bounds()
r := image.NewNRGBA(b)
for x := b.Min.X; x < b.Max.X; x++ {
for y := b.Min.Y; y < b.Max.Y; y++ {
r.Set(x, y, img.At(x, y))
}
}
return r
}

View File

@ -50,7 +50,7 @@ func main() {
if *imgPath != "" { if *imgPath != "" {
offset := image.Pt(*x, *y) offset := image.Pt(*x, *y)
img := readImage(*imgPath) img := imgToNRGBA(readImage(*imgPath))
// check connectivity by opening one test connection // check connectivity by opening one test connection
conn, err := net.Dial("tcp", *address) conn, err := net.Dial("tcp", *address)

View File

@ -14,7 +14,7 @@ import (
// using `conns` connections. Pixels are sent column wise, unless `shuffle` // using `conns` connections. Pixels are sent column wise, unless `shuffle`
// is set. Stops when stop is closed. // is set. Stops when stop is closed.
// @cleanup: use FlutTask{} as arg // @cleanup: use FlutTask{} as arg
func Flut(img image.Image, position image.Point, shuffle bool, address string, conns int, stop chan bool, wg *sync.WaitGroup) { func Flut(img *image.NRGBA, position image.Point, shuffle bool, address string, conns int, stop chan bool, wg *sync.WaitGroup) {
cmds := commandsFromImage(img, position) cmds := commandsFromImage(img, position)
if shuffle { if shuffle {
cmds.Shuffle() cmds.Shuffle()

View File

@ -33,16 +33,14 @@ func (c commands) Shuffle() {
} }
// CommandsFromImage converts an image to the respective pixelflut commands // CommandsFromImage converts an image to the respective pixelflut commands
func commandsFromImage(img image.Image, offset image.Point) (cmds commands) { func commandsFromImage(img *image.NRGBA, offset image.Point) (cmds commands) {
b := img.Bounds() b := img.Bounds()
cmds = make([][]byte, b.Size().X*b.Size().Y) cmds = make([][]byte, b.Size().X*b.Size().Y)
numCmds := 0 numCmds := 0
for x := b.Min.X; x < b.Max.X; x++ { for x := b.Min.X; x < b.Max.X; x++ {
for y := b.Min.Y; y < b.Max.Y; y++ { for y := b.Min.Y; y < b.Max.Y; y++ {
// ensure we're working with RGBA colors (non-alpha-pre-multiplied) c := img.At(x, y).(color.NRGBA)
c := color.NRGBAModel.Convert(img.At(x, y)).(color.NRGBA)
// ignore transparent pixels // ignore transparent pixels
if c.A == 0 { if c.A == 0 {
continue continue

View File

@ -32,7 +32,7 @@ type Hevring struct {
type FlutTask struct { type FlutTask struct {
Address string Address string
MaxConns int MaxConns int
Img *image.NRGBA // bug :imageType: should be image.Image, but can't be serialized. do conversion in task creation? Img *image.NRGBA
Offset image.Point Offset image.Point
Shuffle bool Shuffle bool
} }

View File

@ -115,13 +115,12 @@ func SummonRán(address string, stopChan chan bool, wg *sync.WaitGroup) *Rán {
} }
// SetTask assigns a FlutTask to Rán, distributing it to all clients // SetTask assigns a FlutTask to Rán, distributing it to all clients
func (r *Rán) SetTask(img image.Image, offset image.Point, address string, maxConns int) { func (r *Rán) SetTask(img *image.NRGBA, offset image.Point, address string, maxConns int) {
// @incomplete: smart task creation: // @incomplete: smart task creation:
// fetch server state & sample foreign activity in image regions. assign // fetch server state & sample foreign activity in image regions. assign
// subregions to clients (per connection), considering their bandwidth. // subregions to clients (per connection), considering their bandwidth.
// @bug :imageType r.task = FlutTask{address, maxConns, img, offset, true}
r.task = FlutTask{address, maxConns, img.(*image.NRGBA), offset, true}
for _, c := range r.clients { for _, c := range r.clients {
ack := FlutAck{} ack := FlutAck{}
// @speed: should send tasks async // @speed: should send tasks async