Hey folks,

I'm working on animating gifs in GD. I've adapted the use of the GIFEncoder class from phpclasses.
original
gif.php

<?php


Class GIFAnimator {
    var $GIF = "GIF89a";       
    var $VER = "GIFEncoder V2.05";    

    var $BUF = Array ( );
    var $LOP =  0;
    var $DIS =  2;
    var $COL = -1;
    var $IMG = -1;

    var $ERR = Array (
        ERR00=>"Does not supported function for only one image!",
        ERR01=>"Source is not a GIF image!",
        ERR02=>"Unintelligible flag ",
        ERR03=>"Does not make animation from animated GIF source",
    );

   
    function GIFAnimator    (
                            $GIF_src, $GIF_dly, $GIF_lop, $GIF_dis,
                            $GIF_red, $GIF_grn, $GIF_blu, $GIF_mod
                        ) {
        if ( ! is_array ( $GIF_src ) && ! is_array ( $GIF_tim ) ) {
            printf    ( "%s: %s", $this->VER, $this->ERR [ 'ERR00' ] );
            exit    ( 0 );
        }
        $this->LOP = ( $GIF_lop > -1 ) ? $GIF_lop : 0;
        $this->DIS = ( $GIF_dis > -1 ) ? ( ( $GIF_dis < 3 ) ? $GIF_dis : 3 ) : 2;
        $this->COL = ( $GIF_red > -1 && $GIF_grn > -1 && $GIF_blu > -1 ) ?
                        ( $GIF_red | ( $GIF_grn << 8 ) | ( $GIF_blu << 16 ) ) : -1;

        for ( $i = 0; $i < count ( $GIF_src ); $i++ ) {
            if ( strToLower ( $GIF_mod ) == "url" ) {
                $this->BUF [ ] = fread ( fopen ( $GIF_src [ $i ], "rb" ), filesize ( $GIF_src [ $i ] ) );
            }
            else if ( strToLower ( $GIF_mod ) == "bin" ) {
                $this->BUF [ ] = $GIF_src [ $i ];
            }
            else {
                printf    ( "%s: %s ( %s )!", $this->VER, $this->ERR [ 'ERR02' ], $GIF_mod );
                exit    ( 0 );
            }
            if ( substr ( $this->BUF [ $i ], 0, 6 ) != "GIF87a" && substr ( $this->BUF [ $i ], 0, 6 ) != "GIF89a" ) {
                printf    ( "%s: %d %s", $this->VER, $i, $this->ERR [ 'ERR01' ] );
                exit    ( 0 );
            }
            for ( $j = ( 13 + 3 * ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ) ), $k = TRUE; $k; $j++ ) {
                switch ( $this->BUF [ $i ] { $j } ) {
                    case "!":
                        if ( ( substr ( $this->BUF [ $i ], ( $j + 3 ), 8 ) ) == "NETSCAPE" ) {
                            printf    ( "%s: %s ( %s source )!", $this->VER, $this->ERR [ 'ERR03' ], ( $i + 1 ) );
                            exit    ( 0 );
                        }
                        break;
                    case ";":
                        $k = FALSE;
                        break;
                }
            }
        }
        GIFAnimator::GIFHead ( );
        for ( $i = 0; $i < count ( $this->BUF ); $i++ ) {
            GIFAnimator::GIFGetFrames ( $i, $GIF_dly [ $i ] );
        }
        GIFAnimator::GIFFoot ( );
    }
   
    function GIFHead ( ) {
        $cmap = 0;

        if ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x80 ) {
            $cmap = 3 * ( 2 << ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x07 ) );

            $this->GIF .= substr ( $this->BUF [ 0 ], 6, 7        );
            $this->GIF .= substr ( $this->BUF [ 0 ], 13, $cmap    );
            $this->GIF .= "!\377\13NETSCAPE2.0\3\1" . GIFAnimator::GIFWord ( $this->LOP ) . "\0";
        }
    }
  
    function GIFGetFrames ( $i, $d ) {

        $Locals_str = 13 + 3 * ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) );

        $Locals_end = strlen ( $this->BUF [ $i ] ) - $Locals_str - 1;
        $Locals_tmp = substr ( $this->BUF [ $i ], $Locals_str, $Locals_end );

        $Global_len = 2 << ( ord ( $this->BUF [ 0  ] { 10 } ) & 0x07 );
        $Locals_len = 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 );

        $Global_rgb = substr ( $this->BUF [ 0  ], 13,
                            3 * ( 2 << ( ord ( $this->BUF [ 0  ] { 10 } ) & 0x07 ) ) );
        $Locals_rgb = substr ( $this->BUF [ $i ], 13,
                            3 * ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ) );

        $Locals_ext = "!\xF9\x04" . chr ( ( $this->DIS << 2 ) + 0 ) .
                        chr ( ( $d >> 0 ) & 0xFF ) . chr ( ( $d >> 8 ) & 0xFF ) . "\x0\x0";

        if ( $this->COL > -1 && ord ( $this->BUF [ $i ] { 10 } ) & 0x80 ) {
            for ( $j = 0; $j < ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ); $j++ ) {
                if    (
                        ord ( $Locals_rgb { 3 * $j + 0 } ) == ( ( $this->COL >> 16 ) & 0xFF ) &&
                        ord ( $Locals_rgb { 3 * $j + 1 } ) == ( ( $this->COL >>  8 ) & 0xFF ) &&
                        ord ( $Locals_rgb { 3 * $j + 2 } ) == ( ( $this->COL >>  0 ) & 0xFF )
                    ) {
                    $Locals_ext = "!\xF9\x04" . chr ( ( $this->DIS << 2 ) + 1 ) .
                                    chr ( ( $d >> 0 ) & 0xFF ) . chr ( ( $d >> 8 ) & 0xFF ) . chr ( $j ) . "\x0";
                    break;
                }
            }
        }
        switch ( $Locals_tmp { 0 } ) {
            case "!":
                $Locals_img = substr ( $Locals_tmp, 8, 10 );
                $Locals_tmp = substr ( $Locals_tmp, 18, strlen ( $Locals_tmp ) - 18 );
                break;
            case ",":
                $Locals_img = substr ( $Locals_tmp, 0, 10 );
                $Locals_tmp = substr ( $Locals_tmp, 10, strlen ( $Locals_tmp ) - 10 );
                break;
        }
        if ( ord ( $this->BUF [ $i ] { 10 } ) & 0x80 && $this->IMG > -1 ) {
            if ( $Global_len == $Locals_len ) {
                if ( GIFAnimator::GIFBlock ( $Global_rgb, $Locals_rgb, $Global_len ) ) {
                    $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_tmp );
                }
                else {
                    $byte  = ord ( $Locals_img { 9 } );
                    $byte |= 0x80;
                    $byte &= 0xF8;
                    $byte |= ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x07 );
                    $Locals_img { 9 } = chr ( $byte );
                    $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp );
                }
            }
            else {
                $byte  = ord ( $Locals_img { 9 } );
                $byte |= 0x80;
                $byte &= 0xF8;
                $byte |= ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 );
                $Locals_img { 9 } = chr ( $byte );
                $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp );
            }
        }
        else {
            $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_tmp );
        }
        $this->IMG  = 1;
    }
    
    function GIFFoot ( ) {
        $this->GIF .= ";";
    }
   
    function GIFBlock ( $GlobalBlock, $LocalBlock, $Len ) {

        for ( $i = 0; $i < $Len; $i++ ) {
            if    (
                    $GlobalBlock { 3 * $i + 0 } != $LocalBlock { 3 * $i + 0 } ||
                    $GlobalBlock { 3 * $i + 1 } != $LocalBlock { 3 * $i + 1 } ||
                    $GlobalBlock { 3 * $i + 2 } != $LocalBlock { 3 * $i + 2 }
                ) {
                    return ( 0 );
            }
        }

        return ( 1 );
    }
   
    function GIFWord ( $int ) {

        return ( chr ( $int & 0xFF ) . chr ( ( $int >> 8 ) & 0xFF ) );
    }
    
    function GetAnimation ( ) {
        return ( $this->GIF );
    }
} 

?>

I have used

<?php

include('gif.php');

$image = imagecreatefrompng("../mychatbox/user/helraizer1.png");


if ( $dh = opendir ( "frames/" ) ) {

    while ( false !== ( $dat = readdir ( $dh ) ) ) {

        if ( $dat != "." && $dat != ".." ) {

            $frames [ ] .= "frames/$dat";

            $framed [ ] = 20;

        }

    }

    closedir ( $dh );

}
   
    foreach( $frames as $thePfhrame )
   
      {
   
          $imgPfhrame = imagecreatefromgif($thePfhrame);
   
          imagecopymerge($image, $imgPfhrame, imageSX($image)/2, imageSY($image)/1.5, 0, 0, 15, 15, 100);
   
          
          
        
      }
      

  $gif = new GIFAnimator    (

                            $frames, //sources - URL or path

                            $framed, //delay times - int

                            0, //Animation loops - int - 0 is infinite

                            2, //Disposal - int

                            -1, -1, -1, //transparency red, green, blue - int

                            "url" // source type

        );
   
   
    

       

        header("Content-Type: image/gif");

echo $gif->GetAnimation();


FWrite ( FOpen ( "img.gif", "wb" ), $gif->GetAnimation ( ) );


?>

and it produces this:

[IMG]http://www.helraizer.co.uk/ocr/img.gif[/IMG]

As you can see the one that is in middle is animated! So that works perfectly fine, on its own.

However when I put the code in my showimage script (to produce the shoutbox), which is in a different folder, but still has a 'frames' folder with the same frames in it, it gives me the error.

GIFEncoder V2.05: Does not supported function for only one image!

Even though there are 9 frames in the folder.

if(stristr($line, ":roll:")) {
			session_register("roll");
			$_SESSION['roll'] = 1;
		}
       
if (isset($filter)) {
header("Content-Type: image/png"); // tell the browser what we're gonna give it
    imagepng($image);

} elseif ($page == 1) {

if(!isset($_SESSION['roll'])) {
	header("Content-Type: image/png"); // tell the browser what we're gonna give it
    imagepng($image);
 imagepng($image, "./user/" . $user . $box. ".png");

} else {
	
	 $pos = strpos($line, ":roll:");

        if ($font == "palab") {
            $post = $pos * 5.7;
        } elseif ($font == "comicsans") {
            $post = $pos * 6.725;
        } elseif ($font == "calibri") {
            $post = $pos * 5;
        } elseif ($font == "courbd") {
            $post = ($pos * 5.8) + 1;
        } elseif ($font == "arial") {
            $post = ($pos * 7.3) + 1;
        } else {

        }
	

      		
      if ( $dh = opendir ( "frames/" ) ) {

    while ( false !== ( $dat = readdir ( $dh ) ) ) {

        if ( $dat != "." && $dat != ".." ) {

            $frames [ ] .= "frames/$dat";

            $framed [ ] = 17;

        }

    }

    closedir ( $dh );

}
   
    foreach( $frames as $thePfhrame )
   
      {
   
          $imgPfhrame = imagecreatefromgif($thePfhrame);
   
          imagecopymerge($image, $imgPfhrame, ($cur_line_x + $post) + 6, (($cur_line_y + $lineheight) - 30.5), 0, 0, 15, 15, 100);
   
          
          
        
      }
      

  $gif = new GIFAnimator    (

                            $frames, //sources - URL or path

                            $framed, //delay times - int

                            0, //Animation loops - int - 0 is infinite

                            2, //Disposal - int

                            -1, -1, -1, //transparency red, green, blue - int

                            "url" // source type

        );
   
   
    

       

        header("Content-Type: image/gif");

echo $gif->GetAnimation();


FWrite ( FOpen ( "helraizer2.gif", "wb" ), $gif->GetAnimation ( ) );

}


else {
	header("Content-Type: image/png"); // tell the browser what we're gonna give it
    imagepng($image);

}

The error comes about if $frames isn't an array but, it is. Any idea why this happens?

Sam

Recommended Answers

All 3 Replies

on line 26 of gif.php there is

if ( ! is_array ( $GIF_src ) && ! is_array ( $GIF_tim ) ) {

but i don't see where $GIF_tim is coming from. should it be $GIF_dly?

on line 26 of gif.php there is

if ( ! is_array ( $GIF_src ) && ! is_array ( $GIF_tim ) ) {

but i don't see where $GIF_tim is coming from. should it be $GIF_dly?

Thanks, that's stopped the first error.

However now an odd result has turned out. The script on its own gives the picture I linked to in my previous post.

However in the code when it's within the showimage script if the characters ':roll:' is found in any of the lines of text on the image it overrides the entire shoutbox image as the animated gif. Just the smiley, not the image with the emoticon on it.

Here is the relevant code, can you see any problems?

$image = imagecreatefromgif("./user/" . $user . "_back.gif");

 $im = ImageCreate($wid, 35);
        $black_a = imagecolorallocate($im, 0, 0, 0);
        $white_a = imagecolortransparent($im, $black_a);
        $white = ImageColorAllocate($im, 255, 255, 255);
        ImageFill($im, 0, 0, $white_a);
        Imagettftext($im, 15, 0, 10, 30, $white, $font, $top);

 $cur_line_y = 59;


 $imgs = imagecreatetruecolor($wid, 35);
        $blark = imagecolorallocate($imgs, 0, 0, 0);
        $whitre = imagecolortransparent($imgs, $blark);
        $whiter = imagecolorallocate($imgs, 255, 255, 255);
        ImageFill($imgs, 0, 0, $whitre);
        imagettftext($imgs, 10, 2, 10, 30, $whiter, $fontstick, "JustShout!");


$sql = "SELECT * FROM user INNER JOIN tblcomments ON tblcomments.user_id=user.user_id INNER JOIN tblattributes ON tblcomments.id = tblattributes.id INNER JOIN tblip ON tblattributes.id = tblip.id  WHERE tblcomments.user_id='$user_id' AND tblattributes.user_id='$user_id' AND tblip.user_id='$user_id' AND tblcomments.box_id=$box AND tblattributes.box_id=$box AND tblip.box_id=$box ORDER BY tblcomments.`id` DESC $max";

$result = mysql_query($sql) or die("error in  sqllls: " . mysql_error());


$cur_line_x = 24; // This stores how far across the image the current line will print
$pagecharwidth = 75; // this is the maximum length of the line before it wraps;
$lineheight = 18; // This is how much to move down to print the next line
$pagelinelimit = 1; // This is the maximum number lines of text that can be displayed


for ($i = 0; $i < $numberOfLines; $i++) {
    while ($row = mysql_fetch_array($result)) {

        $count = mysql_num_rows($result);

        $name = "[" . htmlspecialchars_decode($row['username']) . "] "; //it works - returns username
        $font = trim($row['font']); //it works - renders the colour
        $color = trim($row['color']); //it works - changes the font
        $oldline = htmlspecialchars_decode($row['comment']); //it works, posts the shout
        $array = array("\r\n", "\n", "\r");
        $replace = " ";
        $line = str_replace($array, $replace, $oldline);


if ($back == "m" || $col == "a") {

            $whit = imagecolorallocate($image, 255, 255, 255);

            if ($color == "white" || $color == "yellow" || $color == "green" || $color ==
                "orange" || $color == "aqua") {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, getColor($color), getfont
                    ($font), trim($line));


            } elseif ($color != "white" || $color != "yellow" || $color != "green" || $color !=
            "orange" || $color != "aqua") {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, $whit, getfont($font),
                    trim($line));


            } elseif ($font == "fixedsys" || $font == "Courbd" || $font == "arial" || $font ==
            "timesnr" || $font == "calibri" || $font == "comicsans" || $font == "palab") {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, getColor($color), getfont
                    ($font), trim($line));


            } else {
                Imagettftext($image, 10, 0, $cur_line_x, $cur_line_y, $whit, "courbd.ttf", trim
                    ($line));


            }


        $cur_line_y += $lineheight;


        

  }
}

 if(!stristr($line, ":roll:"))  {
	header("Content-Type: image/png"); // tell the browser what we're gonna give it
    imagepng($image);
 imagepng($image, "./user/" . $user . $box. ".png");

} else {
	
	 $pos = strpos($line, ":roll:");

        if ($font == "palab") {
            $post = $pos * 5.7;
        } elseif ($font == "comicsans") {
            $post = $pos * 6.725;
        } elseif ($font == "calibri") {
            $post = $pos * 5;
        } elseif ($font == "courbd") {
            $post = ($pos * 5.8) + 1;
        } elseif ($font == "arial") {
            $post = ($pos * 7.3) + 1;
        } else {

        }
	

      		
      if ( $dh = opendir ( "frames/" ) ) {

    while ( false !== ( $dat = readdir ( $dh ) ) ) {

        if ( $dat != "." && $dat != ".." ) {

            $frames [ ] .= "frames/$dat";

            $framed [ ] = 17;

        }

    }

    closedir ( $dh );

}
   
    foreach( $frames as $thePfhrame )
   
      {
   
          $imgPfhrame = imagecreatefromgif($thePfhrame);
   
          imagecopymerge($image, $imgPfhrame, ($cur_line_x + $post) + 6, (($cur_line_y + $lineheight) - 30.5), 0, 0, 15, 15, 100);
   
          
          
        
      }
      

  $gif = new GIFAnimator    (

                            $frames, //sources - URL or path

                            $framed, //delay times - int

                            0, //Animation loops - int - 0 is infinite

                            2, //Disposal - int

                            -1, -1, -1, //transparency red, green, blue - int

                            "url" // source type

        );
   
   
    

       

        header("Content-Type: image/gif");

echo $gif->GetAnimation();


FWrite ( FOpen ( "helraizer2.gif", "wb" ), $gif->GetAnimation ( ) );

}

Sam

it looks like you are overwriting the entire image with the animation when a ':roll:' character is introduced.

image creation is not my favorite thing in php so my suggestion may be useless.

Be a part of the DaniWeb community

We're a friendly, industry-focused community of developers, IT pros, digital marketers, and technology enthusiasts meeting, networking, learning, and sharing knowledge.