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 [email protected] 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.01 0.02 0.04 0.05 0.06 0.07 0.08 0.1 0.11 ,
            
0.12 0.14 0.15 0.16 0.17 0.18 0.20 0.21 0.22 0.24 ,
            
0.25 0.27 0.28 0.30 0.32 0.34 0.36 0.38 0.40 0.42 ,
            
0.44 0.46 0.48 0.5 0.53 0.56 0.59 0.62 0.65 0.68
            
0.71 0.74 0.77 0.80 0.83 0.86 0.89 0.92 0.95 0.98 ,
            
1.0 1.06 1.12 1.18 1.24 1.30 1.36 1.42 1.48 1.54 ,
            
1.60 1.66 1.72 1.78 1.84 1.90 1.96 2.0 2.12 2.25
            
2.37 2.50 2.62 2.75 2.87 3.0 3.2 3.4 3.6 3.8 ,
            
4.0 4.3 4.7 4.9 5.0 5.5 6.0 6.5 6.8 7.0 ,
            
7.3 7.5 7.8 8.0 8.4 8.7 9.0 9.4 9.6 9.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( 0 20 );
        }

//  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;
        }
    }
}

 

你可能感兴趣的:(Matrix)