101 lines
2.4 KiB
Go
101 lines
2.4 KiB
Go
package raster
|
|
|
|
import (
|
|
"math"
|
|
"math/rand"
|
|
)
|
|
|
|
// Grmap parallels Bitmap, but with an element type of uint16
|
|
// in place of Pixel.
|
|
type Grmap struct {
|
|
Comments []string
|
|
rows, cols int
|
|
px []uint16
|
|
pxRow [][]uint16
|
|
}
|
|
|
|
// NewGrmap constructor.
|
|
func NewGrmap(x, y int) (b *Grmap) {
|
|
g := &Grmap{
|
|
Comments: []string{creator}, // creator a const in bitmap source file
|
|
rows: y,
|
|
cols: x,
|
|
px: make([]uint16, x*y),
|
|
pxRow: make([][]uint16, y),
|
|
}
|
|
x0, x1 := 0, x
|
|
for i := range g.pxRow {
|
|
g.pxRow[i] = g.px[x0:x1]
|
|
x0, x1 = x1, x1+x
|
|
}
|
|
return g
|
|
}
|
|
|
|
func (b *Grmap) Extent() (cols, rows int) {
|
|
return b.cols, b.rows
|
|
}
|
|
|
|
func (g *Grmap) Fill(c uint16) {
|
|
for i := range g.px {
|
|
g.px[i] = c
|
|
}
|
|
}
|
|
|
|
func (g *Grmap) SetPx(x, y int, c uint16) bool {
|
|
defer func() { recover() }()
|
|
g.pxRow[y][x] = c
|
|
return true
|
|
}
|
|
|
|
func (g *Grmap) GetPx(x, y int) (uint16, bool) {
|
|
defer func() { recover() }()
|
|
return g.pxRow[y][x], true
|
|
}
|
|
|
|
// Grmap method of Bitmap, converts (color) Bitmap to (grayscale) Grmap
|
|
func (b *Bitmap) Grmap() *Grmap {
|
|
g := NewGrmap(b.cols, b.rows)
|
|
g.Comments = append([]string{}, b.Comments...)
|
|
for i, p := range b.px {
|
|
g.px[i] = uint16((int64(p.R)*2126 + int64(p.G)*7152 + int64(p.B)*722) *
|
|
math.MaxUint16 / (math.MaxUint8 * 10000))
|
|
}
|
|
return g
|
|
}
|
|
|
|
// Bitmap method Grmap, converts Grmap to Bitmap. All pixels in the resulting
|
|
// color Bitmap will be (very nearly) shades of gray.
|
|
func (g *Grmap) Bitmap() *Bitmap {
|
|
b := NewBitmap(g.cols, g.rows)
|
|
b.Comments = append([]string{}, g.Comments...)
|
|
for i, p := range g.px {
|
|
roundedSum := int(p) * 3 * math.MaxUint8 / math.MaxUint16
|
|
rounded := uint8(roundedSum / 3)
|
|
remainder := roundedSum % 3
|
|
b.px[i].R = rounded
|
|
b.px[i].G = rounded
|
|
b.px[i].B = rounded
|
|
if remainder > 0 {
|
|
odd := rand.Intn(3)
|
|
switch odd + (remainder * 3) {
|
|
case 3:
|
|
b.px[i].R++
|
|
case 4:
|
|
b.px[i].G++
|
|
case 5:
|
|
b.px[i].B++
|
|
case 6:
|
|
b.px[i].G++
|
|
b.px[i].B++
|
|
case 7:
|
|
b.px[i].R++
|
|
b.px[i].B++
|
|
case 8:
|
|
b.px[i].R++
|
|
b.px[i].G++
|
|
}
|
|
}
|
|
}
|
|
return b
|
|
}
|