<?PHP

/**
  *
  * imageFiltersIndex
  *
  * A set of filters that works around the image index, changing it.
  * 
  * It requires GD library.
  *
  * If you want to add a new filter (like redizer or greenizer) in this class,
  * please sent it to Roberto Berto <darkelder@php.net>
  *
  * 
  * Main methods:
  * - resource            Should be used to set a GD image resource to work
  *
  * 
  * Currently Filters:
  * - grayscale            Turn an image grayscale [since 1.0]
  * - sepia            Turn an image older than it is [since 1.0]
  * - yellowize            Add a yellow layer in the front of image (transparent or solid) [since 1.0]
  *
  *
  * Usage:
  * 
  *    $img_src        = ImageCreateFromJpeg("image.jpg");
  *    $imageFiltersIndex     = new imageFiltersIndex;
  *    $imageFiltersIndex->resource($img_src);
  *    $imageFiltersIndex->filter([$options1],[$options2,...]);
  *
  *  Where filter is the filter name and $options is a filter option.
  *  All imageFilterIndex should have some defaults filters options, so you do not need to
  *    use options if you do not want to.
  *
  *
  * Example:
  *
  * $img_src_file = "file.jpg";
  * 
  * $img_src=ImageCreateFromJpeg($img_src_file);
  * 
  * $imageFiltersIndex = new imageFiltersIndex;
  * $imageFiltersIndex->resource($img_src);
  * $imageFiltersIndex->sepia();
  * 
  * header("Content-type: image/jpeg");
  * imagejpeg($img_src,"",50);
  *
  *
  * 
  * Resources: 
  * - more filters algorithms at http://www.thecodeproject.com/cs/media/csharpgraphicfilters11.asp (I found 
  *    sepia there. You can get some nice ideas there and submit the filters you wrote here)
  * - a nice color class at http://darkelder.users.phpclasses.org/browse.html/package/479.html
  *
  * @author        Roberto Berto <darkelder@php.net>
  * @colaborators    ??
  * @date        2002-11-29
  * @license         LGPL (http://www.gnu.org/licenses/lgpl.html)
  * @changes        1.0             first version
  *
  *
  * Copyright (C) 2002 Roberto Berto
  * 
  * This library is free software; you can redistribute it and/or
  * modify it under the terms of the GNU Lesser General Public
  * License as published by the Free Software Foundation; either
  * version 2.1 of the License, or (at your option) any later version.
  * 
  * This library is distributed in the hope that it will be useful,
  * but WITHOUT ANY WARRANTY; without even the implied warranty of
  * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE.  See the GNU
  * Lesser General Public License for more details.
  * 
  * You should have received a copy of the GNU Lesser General Public
  * License along with this library; if not, write to the Free Software
  * Foundation, Inc., 59 Temple Place, Suite 330, Boston, MA  02111-1307  USA
  *
  */

class imageFiltersIndex
{
    var    
$resource_image        0;
    var    
$numColors            0;

    
/** 
    * Colors To Work on the palette
    *
    * How many colors the palette should have.
    *
    * Higher value means better quality and more processor
    * use.
    *
    */
    
var $colorsToWork       256;


    
/**
      * Register the Image Resource (from gd)
      *
      * Each new image to be filtred must call this register
      *
       * What it does is set a link to $this->resource_image and
      * get the number of colors and set it to $this->numColors
      *
      * @param    int    $resource_image        GD image resource
      */
    
function resource($resource_image)
    {
        
$this->resource_image        =&    $resource_image;

        if (
function_exists("imagetruecolortopalette")) {
            
imagetruecolortopalette($this->resource_imagetrue$this->colorsToWork);
        }
        
$this->numColors imagecolorstotal($this->resource_image);        
    }

    
/**
      * Turn image to Grayscale
      *
       * The basic of grayscale is that we must turn 3 colors into 1 color.
       *
      * So, if you sum R+B+G and / 3 you will get just one color and you
       *  should use this new color in R, B and G.
      *
      * But, I found on the http://www.thecodeproject.com/cs/media/csharpgraphicfilters11.asp
      *  that if I multiple, instead of multiple by 1/3, each color by .229, .587 and .114 
      *  and add +3 on the color index, we will get a better image. I have not sure the why.
      *
      * @param    float    $rateR        the rate of Red in the new color ($rateR/1000)
      * @param    float    $rateG        the rate of Green in the new color ($rateG/1000)
          * @param      float   $rateB          the rate of Blue in the new color ($rateB/1000)        
      * @param    int    $whiteness     add more some int on the new color ($newcolor += $whiteness)
      */ 
    
function grayscale($rateR .229,$rateG .587,$rateB .114,$whiteness 3)
    {
        for (
$x 0$x $this->numColors$x++)
        {
            
$src_colors    imagecolorsforindex($this->resource_image,$x);
            
$new_color    min(255,abs($src_colors["red"] * $rateR $src_colors["green"] * $rateG $src_colors["blue"] * $rateB) + $whiteness);
            
imagecolorset($this->resource_image,$x,$new_color,$new_color,$new_color);
        }
    }

    
/**
      * Sepia - make image pretends to be older than it really is
      *
      * It basicly turn the image grayscale and add some defined
      * tint on it: R += 30, G += 43, B += -23, so it will appear a very old picture.
      *
      * @param    int    $tintR        how much Red to add
          * @param      int     $tintG          how much Green to add
          * @param      int     $tintB          how much Blue to add
          * @param      float   $rateR          the rate of Red in the new color ($rateR/1000)
          * @param      float   $rateG          the rate of Green in the new color ($rateG/1000)
          * @param      float   $rateB          the rate of Blue in the new color ($rateB/1000)
          * @param      int     $whiteness      add more some int on the new color ($newcolor += $whiteness)
      */
    
function sepia($tintR 80,$tintG 43,$tingB = -23,$rateR .229,$rateG .587,$rateB .114,$whiteness 3)
    {

            for (
$x 0$x $this->numColors$x++)
            {
                    
$src_colors     imagecolorsforindex($this->resource_image,$x);
            
$new_color      min(255,abs($src_colors["red"] * $rateR $src_colors["green"] * $rateG $src_colors["blue"] * $rateB) + $whiteness);
                    
$r              min(255,$new_color $tintR);
                    
$g              min(255,$new_color $tintG);
                    
$b              min(255,$new_color $tintB);
                    
imagecolorset($this->resource_image,$x,$r,$g,$b);
            }
    }


    
/**
      * Add more yellow 
      *
      * It adds a layout of yellow that can be transparent or solid
      * If $intensityA is 255 the image will be 0% transparent (solid). 
      *
      * @param    int $intensityA        how much strong it will be the yellow (Red and Green) (Something between 0-255)
      * @param    int $intensityB        how much weak will be the Blue (>= 2, in the positive limit it will be make BLUE be 0)
      */
    
function yelloize($intensityA 50,$intensityB 3)
    {
            for (
$x 0$x $this->numColors$x++)
            {
                       
$src_colors     imagecolorsforindex($this->resource_image,$x);
            
$r        min($src_colors["red"] + $intensityA,255);
                    
$g        min($src_colors["green"] + $intensityA,255);
            
$b        max(($r $g) / max($intensityB,2),0);
            
imagecolorset($this->resource_image,$x,$r,$g,$b);
        }
    }


}



?>