1 package limage 2 3 import ( 4 "image" 5 "image/color" 6 7 "vimagination.zapto.org/limage/lcolor" 8 ) 9 10 // RGB is an image of RGB colours. 11 type RGB struct { 12 Pix []lcolor.RGB 13 Stride int 14 Rect image.Rectangle 15 } 16 17 // NewRGB create a new RGB image with the given bounds. 18 func NewRGB(r image.Rectangle) *RGB { 19 w, h := r.Dx(), r.Dy() 20 21 return &RGB{ 22 Pix: make([]lcolor.RGB, w*h), 23 Stride: w, 24 Rect: r, 25 } 26 } 27 28 // At returns the colour at the given coords. 29 func (r *RGB) At(x, y int) color.Color { 30 return r.RGBAt(x, y) 31 } 32 33 // Bounds returns the limits of the image. 34 func (r *RGB) Bounds() image.Rectangle { 35 return r.Rect 36 } 37 38 // ColorModel returns a colour model that converts arbitrary colours to the RGB 39 // space. 40 func (r *RGB) ColorModel() color.Model { 41 return lcolor.RGBModel 42 } 43 44 // RGBAt returns the exact RGB colour at the given coords. 45 func (r *RGB) RGBAt(x, y int) lcolor.RGB { 46 if !(image.Point{x, y}.In(r.Rect)) { 47 return lcolor.RGB{} 48 } 49 50 return r.Pix[r.PixOffset(x, y)] 51 } 52 53 // Opaque just returns true as the alpha channel is fixed. 54 func (r *RGB) Opaque() bool { 55 return true 56 } 57 58 // PixOffset returns the index of the Pix array corresponding to the given 59 // coords. 60 func (r *RGB) PixOffset(x, y int) int { 61 return (y-r.Rect.Min.Y)*r.Stride + x - r.Rect.Min.X 62 } 63 64 // Set converts the given colour to the RGB space and sets it at the given 65 // coords. 66 func (r *RGB) Set(x, y int, c color.Color) { 67 if !(image.Point{x, y}.In(r.Rect)) { 68 return 69 } 70 71 rr, g, b, _ := c.RGBA() 72 r.Pix[r.PixOffset(x, y)] = lcolor.RGB{ 73 R: uint8(rr >> 8), 74 G: uint8(g >> 8), 75 B: uint8(b >> 8), 76 } 77 } 78 79 // SetRGB directly set an RGB colour to the given coords. 80 func (r *RGB) SetRGB(x, y int, rgb lcolor.RGB) { 81 if !(image.Point{x, y}.In(r.Rect)) { 82 return 83 } 84 85 r.Pix[r.PixOffset(x, y)] = rgb 86 } 87 88 // SubImage returns the Image viewable through the given bounds. 89 func (r *RGB) SubImage(rt image.Rectangle) image.Image { 90 rt = rt.Intersect(r.Rect) 91 92 if rt.Empty() { 93 return &RGB{} 94 } 95 96 return &RGB{ 97 Pix: r.Pix[r.PixOffset(rt.Min.X, rt.Min.Y):], 98 Stride: r.Stride, 99 Rect: rt, 100 } 101 } 102