colorm.go (3688B)
1 // Copyright 2014 Hajime Hoshi 2 // 3 // Licensed under the Apache License, Version 2.0 (the "License"); 4 // you may not use this file except in compliance with the License. 5 // You may obtain a copy of the License at 6 // 7 // http://www.apache.org/licenses/LICENSE-2.0 8 // 9 // Unless required by applicable law or agreed to in writing, software 10 // distributed under the License is distributed on an "AS IS" BASIS, 11 // WITHOUT WARRANTIES OR CONDITIONS OF ANY KIND, either express or implied. 12 // See the License for the specific language governing permissions and 13 // limitations under the License. 14 15 package ebiten 16 17 import ( 18 "fmt" 19 20 "image/color" 21 22 "github.com/hajimehoshi/ebiten/v2/internal/affine" 23 ) 24 25 // ColorMDim is a dimension of a ColorM. 26 const ColorMDim = affine.ColorMDim 27 28 // A ColorM represents a matrix to transform coloring when rendering an image. 29 // 30 // A ColorM is applied to the straight alpha color 31 // while an Image's pixels' format is alpha premultiplied. 32 // Before applying a matrix, a color is un-multiplied, and after applying the matrix, 33 // the color is multiplied again. 34 // 35 // The initial value is identity. 36 type ColorM struct { 37 impl *affine.ColorM 38 39 _ [0]func() // Marks as non-comparable. 40 } 41 42 // String returns a string representation of ColorM. 43 func (c *ColorM) String() string { 44 b, t := c.impl.UnsafeElements() 45 return fmt.Sprintf("[[%f, %f, %f, %f, %f], [%f, %f, %f, %f, %f], [%f, %f, %f, %f, %f], [%f, %f, %f, %f, %f]]", 46 b[0], b[4], b[8], b[12], t[0], 47 b[1], b[5], b[9], b[13], t[1], 48 b[2], b[6], b[10], b[14], t[2], 49 b[3], b[7], b[11], b[15], t[3]) 50 } 51 52 // Reset resets the ColorM as identity. 53 func (c *ColorM) Reset() { 54 c.impl = nil 55 } 56 57 // Apply pre-multiplies a vector (r, g, b, a, 1) by the matrix 58 // where r, g, b, and a are clr's values in straight-alpha format. 59 // In other words, Apply calculates ColorM * (r, g, b, a, 1)^T. 60 func (c *ColorM) Apply(clr color.Color) color.Color { 61 return c.impl.Apply(clr) 62 } 63 64 // Concat multiplies a color matrix with the other color matrix. 65 // This is same as muptiplying the matrix other and the matrix c in this order. 66 func (c *ColorM) Concat(other ColorM) { 67 c.impl = c.impl.Concat(other.impl) 68 } 69 70 // Scale scales the matrix by (r, g, b, a). 71 func (c *ColorM) Scale(r, g, b, a float64) { 72 c.impl = c.impl.Scale(float32(r), float32(g), float32(b), float32(a)) 73 } 74 75 // Translate translates the matrix by (r, g, b, a). 76 func (c *ColorM) Translate(r, g, b, a float64) { 77 c.impl = c.impl.Translate(float32(r), float32(g), float32(b), float32(a)) 78 } 79 80 // RotateHue rotates the hue. 81 // theta represents rotating angle in radian. 82 func (c *ColorM) RotateHue(theta float64) { 83 c.ChangeHSV(theta, 1, 1) 84 } 85 86 // ChangeHSV changes HSV (Hue-Saturation-Value) values. 87 // hueTheta is a radian value to rotate hue. 88 // saturationScale is a value to scale saturation. 89 // valueScale is a value to scale value (a.k.a. brightness). 90 // 91 // This conversion uses RGB to/from YCrCb conversion. 92 func (c *ColorM) ChangeHSV(hueTheta float64, saturationScale float64, valueScale float64) { 93 c.impl = c.impl.ChangeHSV(hueTheta, float32(saturationScale), float32(valueScale)) 94 } 95 96 // Element returns a value of a matrix at (i, j). 97 func (c *ColorM) Element(i, j int) float64 { 98 return float64(c.impl.Element(i, j)) 99 } 100 101 // SetElement sets an element at (i, j). 102 func (c *ColorM) SetElement(i, j int, element float64) { 103 c.impl = c.impl.SetElement(i, j, float32(element)) 104 } 105 106 // IsInvertible returns a boolean value indicating 107 // whether the matrix c is invertible or not. 108 func (c *ColorM) IsInvertible() bool { 109 return c.impl.IsInvertible() 110 } 111 112 // Invert inverts the matrix. 113 // If c is not invertible, Invert panics. 114 func (c *ColorM) Invert() { 115 c.impl = c.impl.Invert() 116 }