as3 ColorMatrix 调节显示对象的饱和度、色调、对比度、亮度

代码


/**
 * ColorMatrix by Grant Skinner. August 8, 2005
 * Updated to AS3 November 19, 2007
 * Visit www.gskinner.com/blog for documentation, updates and more free code.
 *
 * You may distribute this class freely, provided it is not modified in any way (including
 * removing this header or changing the package path).
 *
 * Please contact info@gskinner.com prior to distributing modified versions of this class.

 *usage:
http://www.gskinner.com/blog/archives/2005/09/flash_8_source.html

 *var cm = new ColorMatrix();
 * cm.adjustColor(20,20,20,20);
 *displayObject.filters = [new ColorMatrixFilter(cm)];
 
*/

package com.gskinner.geom
{

    dynamic 
public class ColorMatrix extends Array
    {

// constant for contrast calculations:
        private static const DELTA_INDEX:Array = [
            
0,    0.010.020.040.050.060.070.080.10.11,
            
0.120.140.150.160.170.180.200.210.220.24,
            
0.250.270.280.300.320.340.360.380.400.42,
            
0.440.460.480.50.530.560.590.620.650.68
            
0.710.740.770.800.830.860.890.920.950.98,
            
1.01.061.121.181.241.301.361.421.481.54,
            
1.601.661.721.781.841.901.962.02.122.25
            
2.372.502.622.752.873.03.23.43.63.8,
            
4.04.34.74.95.05.56.06.56.87.0,
            
7.37.57.88.08.48.79.09.49.69.8
            
10.0
           ];

        
// identity matrix constant:
        private static const IDENTITY_MATRIX:Array = [
            
1,0,0,0,0,
            
0,1,0,0,0,
            
0,0,1,0,0,
            
0,0,0,1,0,
            
0,0,0,0,1
           ];
        
private static const LENGTH:Number = IDENTITY_MATRIX.length;


// initialization:
        public function ColorMatrix(p_matrix:Array = null)
        {
            p_matrix 
= fixMatrix(p_matrix);
            copyMatrix(((p_matrix.length 
== LENGTH) ? p_matrix : IDENTITY_MATRIX));
        }


// public methods:
        public function reset():void
        {
            
for (var i:uint = 0; i < LENGTH; i++)
            {
                
this[i] = IDENTITY_MATRIX[i];
            }
        }

        
public function adjustColor(p_brightness:Number, p_contrast:Number, p_saturation:Number, p_hue:Number):void
        {
            adjustHue(p_hue);
            adjustContrast(p_contrast);
            adjustBrightness(p_brightness);
            adjustSaturation(p_saturation);
        }

        
public function adjustBrightness(p_val:Number):void
        {
            p_val 
= cleanValue(p_val, 100);
            
if (p_val == 0 || isNaN(p_val))
            {
                
return;
            }
             multiplyMatrix([
                 
1,0,0,0,p_val,
                 
0,1,0,0,p_val,
                 
0,0,1,0,p_val,
                 
0,0,0,1,0,
                 
0,0,0,0,1
                ]);
        }

        
public function adjustContrast(p_val:Number):void
        {
            p_val 
= cleanValue(p_val, 100);
            
if (p_val == 0 || isNaN(p_val))
            {
                
return;
            }
            var x:Number;
            
if (p_val < 0)
            {
                x 
= 127 + p_val / 100 * 127
            }
            
else
            {
                x 
= p_val % 1;
                
if (x == 0)
                {
                    x 
= DELTA_INDEX[p_val];
                }
                
else
                {
                    
//x = DELTA_INDEX[(p_val<<0)]; // this is how the IDE does it.
                    x = DELTA_INDEX[(p_val << 0)] * (1 - x) + DELTA_INDEX[(p_val << 0+ 1* x; // use linear interpolation for more granularity.
                }
                x 
= x * 127 + 127;
            }
            multiplyMatrix([
                 x
/127,0,0,0,0.5*(127-x),
                 
0,x/127,0,0,0.5*(127-x),
                 
0,0,x/127,0,0.5*(127-x),
                 
0,0,0,1,0,
                 
0,0,0,0,1
                ]);

        }

        
public function adjustSaturation(p_val:Number):void
        {
            p_val 
= cleanValue(p_val, 100);
            
if (p_val == 0 || isNaN(p_val))
            {
                
return;
            }
            var x:Number 
= 1 + ((p_val > 0? 3 * p_val / 100 : p_val / 100);
            var lumR:Number 
= 0.3086;
            var lumG:Number 
= 0.6094;
            var lumB:Number 
= 0.0820;
            multiplyMatrix([
                 lumR
*(1-x)+x,lumG*(1-x),lumB*(1-x),0,0,
                 lumR
*(1-x),lumG*(1-x)+x,lumB*(1-x),0,0,
                 lumR
*(1-x),lumG*(1-x),lumB*(1-x)+x,0,0,
                 
0,0,0,1,0,
                 
0,0,0,0,1
                ]);

        }

        
public function adjustHue(p_val:Number):void
        {
            p_val 
= cleanValue(p_val, 180/ 180 * Math.PI;
            
if (p_val == 0 || isNaN(p_val))
            {
                
return;
            }
            var cosVal:Number 
= Math.cos(p_val);
            var sinVal:Number 
= Math.sin(p_val);
            var lumR:Number 
= 0.213;
            var lumG:Number 
= 0.715;
            var lumB:Number 
= 0.072;
            multiplyMatrix([
                 lumR
+cosVal*(1-lumR)+sinVal*(-lumR),lumG+cosVal*(-lumG)+sinVal*(-lumG),lumB+cosVal*(-lumB)+sinVal*(1-lumB),0,0,
                 lumR
+cosVal*(-lumR)+sinVal*(0.143),lumG+cosVal*(1-lumG)+sinVal*(0.140),lumB+cosVal*(-lumB)+sinVal*(-0.283),0,0,
                 lumR
+cosVal*(-lumR)+sinVal*(-(1-lumR)),lumG+cosVal*(-lumG)+sinVal*(lumG),lumB+cosVal*(1-lumB)+sinVal*(lumB),0,0,
                 
0,0,0,1,0,
                 
0,0,0,0,1
                ]);

        }

        
public function concat(p_matrix:Array):void
        {
            p_matrix 
= fixMatrix(p_matrix);
            
if (p_matrix.length != LENGTH)
            {
                
return;
            }
            multiplyMatrix(p_matrix);
        }

        
public function clone():ColorMatrix
        {
            
return new ColorMatrix(this);
        }

        
public function toString():String
        {
            
return "ColorMatrix [ " + this.join(" , "+ " ]";
        }

        
// return a length 20 array (5x4):
        public function toArray():Array
        {
            
return slice(020);
        }

// private methods:
        
// copy the specified matrix's values to this matrix:
        protected function copyMatrix(p_matrix:Array):void
        {
            var l:Number 
= LENGTH;
            
for (var i:uint = 0; i < l; i++)
            {
                
this[i] = p_matrix[i];
            }
        }

        
// multiplies one matrix against another:
        protected function multiplyMatrix(p_matrix:Array):void
        {
            var col:Array 
= [];

            
for (var i:uint = 0; i < 5; i++)
            {
                
for (var j:uint = 0; j < 5; j++)
                {
                    col[j] 
= this[j + i * 5];
                }
                
for (j = 0; j < 5; j++)
                {
                    var val:Number 
= 0;
                    
for (var k:Number = 0; k < 5; k++)
                    {
                        val 
+= p_matrix[j + k * 5* col[k];
                    }
                    
this[j + i * 5= val;
                }
            }
        }

        
// make sure values are within the specified range, hue has a limit of 180, others are 100:
        protected function cleanValue(p_val:Number, p_limit:Number):Number
        {
            
return Math.min(p_limit, Math.max(-p_limit, p_val));
        }

        
// makes sure matrixes are 5x5 (25 long):
        protected function fixMatrix(p_matrix:Array = null):Array
        {
            
if (p_matrix == null)
            {
                
return IDENTITY_MATRIX;
            }
            
if (p_matrix is ColorMatrix)
            {
                p_matrix 
= p_matrix.slice(0);
            }
            
if (p_matrix.length < LENGTH)
            {
                p_matrix 
= p_matrix.slice(0, p_matrix.length).concat(IDENTITY_MATRIX.slice(p_matrix.length, LENGTH));
            }
            
else if (p_matrix.length > LENGTH)
            {
                p_matrix 
= p_matrix.slice(0, LENGTH);
            }
            
return p_matrix;
        }
    }
}

原文地址:https://www.cnblogs.com/sevenyuan/p/1615508.html