Jump to content

GD Animated Gifs


helraizer

Recommended Posts

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.gif

 

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. + 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

Link to comment
Share on other sites

This thread is more than a year old. Please don't revive it unless you have something important to add.

Join the conversation

You can post now and register later. If you have an account, sign in now to post with your account.

Guest
Reply to this topic...

×   Pasted as rich text.   Restore formatting

  Only 75 emoji are allowed.

×   Your link has been automatically embedded.   Display as a link instead

×   Your previous content has been restored.   Clear editor

×   You cannot paste images directly. Upload or insert images from URL.

×
×
  • Create New...

Important Information

We have placed cookies on your device to help make this website better. You can adjust your cookie settings, otherwise we'll assume you're okay to continue.