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 return &RGB{ 21 Pix: make([]lcolor.RGB, w*h), 22 Stride: w, 23 Rect: r, 24 } 25 } 26 27 // At returns the colour at the given coords 28 func (r *RGB) At(x, y int) color.Color { 29 return r.RGBAt(x, y) 30 } 31 32 // Bounds returns the limits of the image 33 func (r *RGB) Bounds() image.Rectangle { 34 return r.Rect 35 } 36 37 // ColorModel returns a colour model that converts arbitrary colours to the RGB 38 // space 39 func (r *RGB) ColorModel() color.Model { 40 return lcolor.RGBModel 41 } 42 43 // RGBAt returns the exact RGB colour at the given coords 44 func (r *RGB) RGBAt(x, y int) lcolor.RGB { 45 if !(image.Point{x, y}.In(r.Rect)) { 46 return lcolor.RGB{} 47 } 48 return r.Pix[r.PixOffset(x, y)] 49 } 50 51 // Opaque just returns true as the alpha channel is fixed. 52 func (r *RGB) Opaque() bool { 53 return true 54 } 55 56 // PixOffset returns the index of the Pix array correspinding to the given 57 // coords 58 func (r *RGB) PixOffset(x, y int) int { 59 return (y-r.Rect.Min.Y)*r.Stride + x - r.Rect.Min.X 60 } 61 62 // Set converts the given colour to the RGB space and sets it at the given 63 // coords 64 func (r *RGB) Set(x, y int, c color.Color) { 65 if !(image.Point{x, y}.In(r.Rect)) { 66 return 67 } 68 rr, g, b, _ := c.RGBA() 69 r.Pix[r.PixOffset(x, y)] = lcolor.RGB{ 70 R: uint8(rr >> 8), 71 G: uint8(g >> 8), 72 B: uint8(b >> 8), 73 } 74 } 75 76 // SetRGB directly set an RGB colour to the given coords 77 func (r *RGB) SetRGB(x, y int, rgb lcolor.RGB) { 78 if !(image.Point{x, y}.In(r.Rect)) { 79 return 80 } 81 r.Pix[r.PixOffset(x, y)] = rgb 82 } 83 84 // SubImage retuns the Image viewable through the given bounds 85 func (r *RGB) SubImage(rt image.Rectangle) image.Image { 86 rt = rt.Intersect(r.Rect) 87 if rt.Empty() { 88 return &RGB{} 89 } 90 return &RGB{ 91 Pix: r.Pix[r.PixOffset(rt.Min.X, rt.Min.Y):], 92 Stride: r.Stride, 93 Rect: rt, 94 } 95 } 96