AS3 ColorMatrix Class


/ Published in: ActionScript 3
Save to your folder(s)

The ColorMatrix class by Grant Skinner allows you to modify the Brightness, Contrast, Saturation and Hue of a DisplayObject.


Copy this code and paste it in your HTML
  1. /**
  2. * ColorMatrix by Grant Skinner. August 8, 2005
  3. * Updated to AS3 November 19, 2007
  4. * Visit www.gskinner.com/blog for documentation, updates and more free code.
  5. *
  6. * You may distribute this class freely, provided it is not modified in any way (including
  7. * removing this header or changing the package path).
  8. *
  9. * Please contact [email protected] prior to distributing modified versions of this class.
  10. */
  11.  
  12. package com.gskinner.geom {
  13.  
  14. dynamic public class ColorMatrix extends Array {
  15.  
  16. // constant for contrast calculations:
  17. private static const DELTA_INDEX:Array = [
  18. 0, 0.01, 0.02, 0.04, 0.05, 0.06, 0.07, 0.08, 0.1, 0.11,
  19. 0.12, 0.14, 0.15, 0.16, 0.17, 0.18, 0.20, 0.21, 0.22, 0.24,
  20. 0.25, 0.27, 0.28, 0.30, 0.32, 0.34, 0.36, 0.38, 0.40, 0.42,
  21. 0.44, 0.46, 0.48, 0.5, 0.53, 0.56, 0.59, 0.62, 0.65, 0.68,
  22. 0.71, 0.74, 0.77, 0.80, 0.83, 0.86, 0.89, 0.92, 0.95, 0.98,
  23. 1.0, 1.06, 1.12, 1.18, 1.24, 1.30, 1.36, 1.42, 1.48, 1.54,
  24. 1.60, 1.66, 1.72, 1.78, 1.84, 1.90, 1.96, 2.0, 2.12, 2.25,
  25. 2.37, 2.50, 2.62, 2.75, 2.87, 3.0, 3.2, 3.4, 3.6, 3.8,
  26. 4.0, 4.3, 4.7, 4.9, 5.0, 5.5, 6.0, 6.5, 6.8, 7.0,
  27. 7.3, 7.5, 7.8, 8.0, 8.4, 8.7, 9.0, 9.4, 9.6, 9.8,
  28. 10.0
  29. ];
  30.  
  31. // identity matrix constant:
  32. private static const IDENTITY_MATRIX:Array = [
  33. 1,0,0,0,0,
  34. 0,1,0,0,0,
  35. 0,0,1,0,0,
  36. 0,0,0,1,0,
  37. 0,0,0,0,1
  38. ];
  39. private static const LENGTH:Number = IDENTITY_MATRIX.length;
  40.  
  41.  
  42. // initialization:
  43. public function ColorMatrix(p_matrix:Array=null) {
  44. p_matrix = fixMatrix(p_matrix);
  45. copyMatrix(((p_matrix.length == LENGTH) ? p_matrix : IDENTITY_MATRIX));
  46. }
  47.  
  48.  
  49. // public methods:
  50. public function reset():void {
  51. for (var i:uint=0; i<LENGTH; i++) {
  52. this[i] = IDENTITY_MATRIX[i];
  53. }
  54. }
  55.  
  56. public function adjustColor(p_brightness:Number,p_contrast:Number,p_saturation:Number,p_hue:Number):void {
  57. adjustHue(p_hue);
  58. adjustContrast(p_contrast);
  59. adjustBrightness(p_brightness);
  60. adjustSaturation(p_saturation);
  61. }
  62.  
  63. public function adjustBrightness(p_val:Number):void {
  64. p_val = cleanValue(p_val,100);
  65. if (p_val == 0 || isNaN(p_val)) { return; }
  66. multiplyMatrix([
  67. 1,0,0,0,p_val,
  68. 0,1,0,0,p_val,
  69. 0,0,1,0,p_val,
  70. 0,0,0,1,0,
  71. 0,0,0,0,1
  72. ]);
  73. }
  74.  
  75. public function adjustContrast(p_val:Number):void {
  76. p_val = cleanValue(p_val,100);
  77. if (p_val == 0 || isNaN(p_val)) { return; }
  78. var x:Number;
  79. if (p_val<0) {
  80. x = 127+p_val/100*127
  81. } else {
  82. x = p_val%1;
  83. if (x == 0) {
  84. x = DELTA_INDEX[p_val];
  85. } else {
  86. //x = DELTA_INDEX[(p_val<<0)]; // this is how the IDE does it.
  87. x = DELTA_INDEX[(p_val<<0)]*(1-x)+DELTA_INDEX[(p_val<<0)+1]*x; // use linear interpolation for more granularity.
  88. }
  89. x = x*127+127;
  90. }
  91. multiplyMatrix([
  92. x/127,0,0,0,0.5*(127-x),
  93. 0,x/127,0,0,0.5*(127-x),
  94. 0,0,x/127,0,0.5*(127-x),
  95. 0,0,0,1,0,
  96. 0,0,0,0,1
  97. ]);
  98. }
  99.  
  100. public function adjustSaturation(p_val:Number):void {
  101. p_val = cleanValue(p_val,100);
  102. if (p_val == 0 || isNaN(p_val)) { return; }
  103. var x:Number = 1+((p_val > 0) ? 3*p_val/100 : p_val/100);
  104. var lumR:Number = 0.3086;
  105. var lumG:Number = 0.6094;
  106. var lumB:Number = 0.0820;
  107. multiplyMatrix([
  108. lumR*(1-x)+x,lumG*(1-x),lumB*(1-x),0,0,
  109. lumR*(1-x),lumG*(1-x)+x,lumB*(1-x),0,0,
  110. lumR*(1-x),lumG*(1-x),lumB*(1-x)+x,0,0,
  111. 0,0,0,1,0,
  112. 0,0,0,0,1
  113. ]);
  114. }
  115.  
  116. public function adjustHue(p_val:Number):void {
  117. p_val = cleanValue(p_val,180)/180*Math.PI;
  118. if (p_val == 0 || isNaN(p_val)) { return; }
  119. var cosVal:Number = Math.cos(p_val);
  120. var sinVal:Number = Math.sin(p_val);
  121. var lumR:Number = 0.213;
  122. var lumG:Number = 0.715;
  123. var lumB:Number = 0.072;
  124. multiplyMatrix([
  125. lumR+cosVal*(1-lumR)+sinVal*(-lumR),lumG+cosVal*(-lumG)+sinVal*(-lumG),lumB+cosVal*(-lumB)+sinVal*(1-lumB),0,0,
  126. lumR+cosVal*(-lumR)+sinVal*(0.143),lumG+cosVal*(1-lumG)+sinVal*(0.140),lumB+cosVal*(-lumB)+sinVal*(-0.283),0,0,
  127. lumR+cosVal*(-lumR)+sinVal*(-(1-lumR)),lumG+cosVal*(-lumG)+sinVal*(lumG),lumB+cosVal*(1-lumB)+sinVal*(lumB),0,0,
  128. 0,0,0,1,0,
  129. 0,0,0,0,1
  130. ]);
  131. }
  132.  
  133. public function concat(p_matrix:Array):void {
  134. p_matrix = fixMatrix(p_matrix);
  135. if (p_matrix.length != LENGTH) { return; }
  136. multiplyMatrix(p_matrix);
  137. }
  138.  
  139. public function clone():ColorMatrix {
  140. return new ColorMatrix(this);
  141. }
  142.  
  143. public function toString():String {
  144. return "ColorMatrix [ "+this.join(" , ")+" ]";
  145. }
  146.  
  147. // return a length 20 array (5x4):
  148. public function toArray():Array {
  149. return slice(0,20);
  150. }
  151.  
  152. // private methods:
  153. // copy the specified matrix's values to this matrix:
  154. protected function copyMatrix(p_matrix:Array):void {
  155. var l:Number = LENGTH;
  156. for (var i:uint=0;i<l;i++) {
  157. this[i] = p_matrix[i];
  158. }
  159. }
  160.  
  161. // multiplies one matrix against another:
  162. protected function multiplyMatrix(p_matrix:Array):void {
  163. var col:Array = [];
  164.  
  165. for (var i:uint=0;i<5;i++) {
  166. for (var j:uint=0;j<5;j++) {
  167. col[j] = this[j+i*5];
  168. }
  169. for (j=0;j<5;j++) {
  170. var val:Number=0;
  171. for (var k:Number=0;k<5;k++) {
  172. val += p_matrix[j+k*5]*col[k];
  173. }
  174. this[j+i*5] = val;
  175. }
  176. }
  177. }
  178.  
  179. // make sure values are within the specified range, hue has a limit of 180, others are 100:
  180. protected function cleanValue(p_val:Number,p_limit:Number):Number {
  181. return Math.min(p_limit,Math.max(-p_limit,p_val));
  182. }
  183.  
  184. // makes sure matrixes are 5x5 (25 long):
  185. protected function fixMatrix(p_matrix:Array=null):Array {
  186. if (p_matrix == null) { return IDENTITY_MATRIX; }
  187. if (p_matrix is ColorMatrix) { p_matrix = p_matrix.slice(0); }
  188. if (p_matrix.length < LENGTH) {
  189. p_matrix = p_matrix.slice(0,p_matrix.length).concat(IDENTITY_MATRIX.slice(p_matrix.length,LENGTH));
  190. } else if (p_matrix.length > LENGTH) {
  191. p_matrix = p_matrix.slice(0,LENGTH);
  192. }
  193. return p_matrix;
  194. }
  195. }
  196. }

URL: http://www.gskinner.com/blog/archives/2007/12/colormatrix_upd.html

Report this snippet


Comments

RSS Icon Subscribe to comments

You need to login to post a comment.