PHP Thumbnail Image script, jpg colours looking funny on thumbnail.

Discussion in 'PHP' started by darksat, Jan 16, 2008.

  1. #1
    I am having problems with this code, it resizes gifs fine but the colour in jpeg is terrible. can anyone give me a hand.

    example code works like so.
    Example: <img src="image.php?img=/imgs/logo.png;sm,200" border="1" alt="[Image]" align="left">
    This will scale the image down to a maximum of 200px while keeping the aspect ratio.

    
    <?php
    session_register( 'imgdir' );
    session_register( 'imgext' );
    $imgext = '.jpg';
    */
    
    if( ! defined( 'IMG_IP' ) ) { define( 'IMG_IP', 1 ); } // Image interpolation -- size up from original
    if( ! defined( 'IMG_MAXSIZE' ) ) { define( 'IMG_MAXSIZE', 999999999 ); } // can't be any larger
    
    class Image
    {
        var $data;
        var $filename;
        var $img;
        
        function Image( $mixed = 0 )
        {
            if( empty( $mixed ) ) { return $this; }
            if( ! $this->ImageFromFile( $mixed ) ) {
                if( ! $this->ImageFromData( $mixed ) ) {
                    return( 0 );
                }
            }
            return $this;    
        }
        
        function ImageFromFile( $f )
        {
            if( ( $fp = fopen( $f, 'rb' ) ) || ($fp = fopen($_SERVER['DOCUMENT_ROOT'] . $f, 'rb')) ) {
                $this->data = fread( $fp, ( filesize( $f ) ? filesize( $f ) : IMG_MAXSIZE ) );
                $this->filename = $f;
                return $this->ImageFromData( $this->data );
            } else {
                return( 0 );
            }
            return( 1 );
        }
        
        function ImageFromData( $d )
        {
            if( $this->img = ImageCreateFromString( $d ) ) {
                return( 1 );
            }
            return( 0 );
        }
        
        function save( $filename = '', $print = 0 )
        {
            if( empty( $filename ) ) {
                if( empty( $this->filename ) ) {
                    return 0;
                } else {
                    $filename = $this->filename;
                }
            }
            //print $filename;
            $filetype = substr( strrchr( $filename, '.' ), 1 );
            switch( $filetype ) {
                case 'jpg':
                case 'jpeg':
                    if( ImageTypes() & IMG_JPG ) {
                        if( $print ) {
                            header( "Content-type: image/jpeg\n\n" );
                            return ImageJPEG( $this->img );
                        } else return ImageJPEG( $this->img, $filename );
                    }
                    break;
                case 'png':
                    if( ImageTypes() & IMG_PNG ) {
                        if( $print ) {
                            header( "Content-type: image/png\n\n" );
                            return ImagePNG( $this->img );
                        } else return ImagePNG( $this->img, $filename );
                    }
                    break;
                case 'gif':
                    if( ImageTypes() & IMG_GIF ) {
                        if( $print ) {
                            header( "Content-type: image/gif\n\n" );
                            return ImageGIF( $this->img );
                        } else return ImageGIF( $this->img, $filename );
                    }
                    break;
                case 'bmp':
                    if( ImageTypes() & IMG_WBMP ) {
                        if( $print ) {
                            header( "Content-type: image/wbmp\n\n" );
                            return ImageWBMP( $this->img );
                        } else return ImageWBMP( $this->img, $filename );
                    }
                    break;
            }
        }
        
        function p()
        {
            return $this->save( 0, 1 );
        }
        
        
        function scale_image( $newWidth = 0, $newHeight = 0, $ratio = 0, $copy = '' )
        {
            if( ! empty( $copy ) ) {
                global $$copy;
            }
    
            $width = imageSX( $this->img );
            $height = imageSY( $this->img );
            if( empty( $newWidth ) &&  empty( $newHeight ) ) {
                // no dimensions, check ratio
                if( empty( $ratio ) ) {
                    // nothing to scale to, return
                    return( 0 );
                } else {
                    // get dimensions from ratio
                    $dimensions[] = round( $width * $ratio );
                    $dimensions[] = round( $height * $ratio );
                }
            } else if( empty( $newWidth ) || empty( $newHeight ) ) {
                // we have one dimension, use this as the max and run through ratio()
                $dimensions = $this->ratio( ( ! empty( $newWidth ) ? $newWidth : $newHeight ) );
            } else {
                $dimensions = array( $newWidth, $newHeight );
            }
    
            $newImg = imageCreate( $dimensions[0], $dimensions[1] );
            imageCopyResized( $newImg, $this->img, 0, 0, 0, 0, $dimensions[0], $dimensions[1], $width, $height );
            if( empty( $copyScaled ) ) {
                imageDestroy( $this->img );
                $this->img = imageCreate( $dimensions[0], $dimensions[1] );
                imageCopy( $this->img, $newImg, 0, 0, 0, 0, $dimensions[0], $dimensions[1] );
            } else {
                $$copy = new Image( imageJpeg( $newImg ) );
            }
            imageDestroy( $newImg );
            return( 1 );
        }
    
        function ratio( $max )
        {
            $width = imageSX( $this->img );
            $height = imageSY( $this->img );
            if( empty( $max ) ) { return( 0 ); }
            $ratio = round( ( $max / max( $width, $height ) ), 2 );
            // work out interpolation (scale larger than original)
            if( ! IMG_IP ) {
                if( $ratio < 1 ) {
                    $width = round( $width * $ratio );
                    $height = round( $height * $ratio );
                }
            } else {
                $width = round( $width * $ratio );
                $height = round( $height * $ratio );
            }
            return( Array( $width, $height, $ratio ) );
    
        }
        
        function overlay( $img, $ovr, $copy = '' )
        {
            
        }
        
        function parseImgTag( $tag )
        {
            /*format '$url;$args'
                args: '$attr,$param[[,$param],$paramX];$attr,$param[[,$param],$paramX]'
            */
            $url = substr( $tag, 0, (strpos( $tag, ';' )?strpos($tag,';'):strlen($tag)) );
            //print $url;
            // load image or die
            
            if( !$this->ImageFromFile( $url ) ) {
                die( "Could not load image" );
            }
            
            $args = substr( strchr( $tag, ';' ), 1 );
            // parse args
            $commands = explode( ';', $args );
            foreach( $commands as $command ) {
                $attr = substr( $command, 0, strpos( $command, ',' ) );
                $params = explode( ',', substr( strchr( $command, ',' ), 1 ) );
                switch( $attr ) {
                    /* s.. Scale functions as follows
                        s,width,height -- scale to desired dimensions
                        sm,max -- scale to maximum
                        sr,ratio -- scale to ratio (relative to 1.0)
                    */
                    case 's':
                        $this->scale_image( $params[0], $params[1] );
                        break;
                    case 'sm':
                        $this->scale_image( $params[0] );
                        break;
                    case 'sr':
                        $this->scale_image( 0, 0, $params[0] );
                        break;
                }
                
            }
            $this->p();
            
        }
    
    }
    
    
    /* main logic if called directly */
    
    if($_SERVER['PATH_TRANSLATED'] == __FILE__) {
        if(isset($_GET['img']) && !empty($_GET['img'])) {
            $imgO = new Image();
    
            $imgO->parseImgTag(urldecode($_GET['img']));
        }
    }
    
    ?> 
    PHP:
     
    darksat, Jan 16, 2008 IP
  2. TechEvangelist

    TechEvangelist Guest

    Messages:
    919
    Likes Received:
    140
    Best Answers:
    0
    Trophy Points:
    133
    #2
    You might want to try using the truecolor method. I think that might be the problem.

    Replace
     
    $newImg = imageCreate( $dimensions[0], $dimensions[1] );
    imageCopyResized( $newImg, $this->img, 0, 0, 0, 0, $dimensions[0], $dimensions[1], $width, $height );
    
    Code (markup):
    with
    
    $newImg = imagecreatetruecolor( $dimensions[0], $dimensions[1] );
    imagecopyresampled($newImg, $this->img, 0, 0, 0, 0, $dimensions[0], $dimensions[1], $width, $height);
    
    Code (markup):
    I always use the truecolor method for thumbnail generation and it produces pretty good results as long as you maintain a proper aspect ratio.

    Note that the second line is changed from imageCopyResized to imagecopyresampled.
     
    TechEvangelist, Jan 16, 2008 IP
  3. decepti0n

    decepti0n Peon

    Messages:
    519
    Likes Received:
    16
    Best Answers:
    0
    Trophy Points:
    0
    #3
    imagejpeg() has a third parameter quality:

    ImageJPEG( $this->img, null, 100 );
    ImageJPEG( $this->img, $filename, 100);
    PHP:
     
    decepti0n, Jan 16, 2008 IP
  4. darksat

    darksat Guest

    Messages:
    1,239
    Likes Received:
    16
    Best Answers:
    0
    Trophy Points:
    0
    #4
    Thanks for the help lads
    Image truecolor was the fix.
    Needed to be added in twice though.

    
    $newImg = imagecreatetruecolor( $dimensions[0], $dimensions[1] );
    imageCopyResampled($newImg, $this->img, 0, 0, 0, 0, $dimensions[0], $dimensions[1], $width, $height);
            if( empty( $copyScaled ) ) {
                imageDestroy( $this->img );
                $this->img = imagecreatetruecolor( $dimensions[0], $dimensions[1] );
    
    PHP:
    Thanks Again.
     
    darksat, Jan 16, 2008 IP