473,796 Members | 2,460 Online
Bytes | Software Development & Data Engineering Community
+ Post

Home Posts Topics Members FAQ

Animating gifs through PHP GD - treat as Image not Object?

118 New Member
Me again :D You're going to be sick of me soon. =P

I found the GifEncoder class on phpclasses, which creates an animated gif image from frames and echos it to the browser to show; can also save it as an image with .gif extension.

The only problem is that I need to add the animated gif onto another image (with imagecopymerge) , however the gif image that is returned by this code in an object.

Here is the code:

GifEncoder.Clas s.php
Expand|Select|Wrap|Line Numbers
  1. <?php
  2.  
  3.  
  4. Class GIFAnimator {
  5.     var $GIF = "GIF89a";       
  6.     var $VER = "GIFEncoder V2.05";    
  7.  
  8.     var $BUF = Array ( );
  9.     var $LOP =  0;
  10.     var $DIS =  2;
  11.     var $COL = -1;
  12.     var $IMG = -1;
  13.  
  14.     var $ERR = Array (
  15.         ERR00=>"Does not supported function for only one image!",
  16.         ERR01=>"Source is not a GIF image!",
  17.         ERR02=>"Unintelligible flag ",
  18.         ERR03=>"Does not make animation from animated GIF source",
  19.     );
  20.  
  21.  
  22.     function GIFAnimator    (
  23.                             $GIF_src, $GIF_dly, $GIF_lop, $GIF_dis,
  24.                             $GIF_red, $GIF_grn, $GIF_blu, $GIF_mod
  25.                         ) {
  26.         if ( ! is_array ( $GIF_src ) && ! is_array ( $GIF_tim ) ) {
  27.             printf    ( "%s: %s", $this->VER, $this->ERR [ 'ERR00' ] );
  28.             exit    ( 0 );
  29.         }
  30.         $this->LOP = ( $GIF_lop > -1 ) ? $GIF_lop : 0;
  31.         $this->DIS = ( $GIF_dis > -1 ) ? ( ( $GIF_dis < 3 ) ? $GIF_dis : 3 ) : 2;
  32.         $this->COL = ( $GIF_red > -1 && $GIF_grn > -1 && $GIF_blu > -1 ) ?
  33.                         ( $GIF_red | ( $GIF_grn << 8 ) | ( $GIF_blu << 16 ) ) : -1;
  34.  
  35.         for ( $i = 0; $i < count ( $GIF_src ); $i++ ) {
  36.             if ( strToLower ( $GIF_mod ) == "url" ) {
  37.                 $this->BUF [ ] = fread ( fopen ( $GIF_src [ $i ], "rb" ), filesize ( $GIF_src [ $i ] ) );
  38.             }
  39.             else if ( strToLower ( $GIF_mod ) == "bin" ) {
  40.                 $this->BUF [ ] = $GIF_src [ $i ];
  41.             }
  42.             else {
  43.                 printf    ( "%s: %s ( %s )!", $this->VER, $this->ERR [ 'ERR02' ], $GIF_mod );
  44.                 exit    ( 0 );
  45.             }
  46.             if ( substr ( $this->BUF [ $i ], 0, 6 ) != "GIF87a" && substr ( $this->BUF [ $i ], 0, 6 ) != "GIF89a" ) {
  47.                 printf    ( "%s: %d %s", $this->VER, $i, $this->ERR [ 'ERR01' ] );
  48.                 exit    ( 0 );
  49.             }
  50.             for ( $j = ( 13 + 3 * ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ) ), $k = TRUE; $k; $j++ ) {
  51.                 switch ( $this->BUF [ $i ] { $j } ) {
  52.                     case "!":
  53.                         if ( ( substr ( $this->BUF [ $i ], ( $j + 3 ), 8 ) ) == "NETSCAPE" ) {
  54.                             printf    ( "%s: %s ( %s source )!", $this->VER, $this->ERR [ 'ERR03' ], ( $i + 1 ) );
  55.                             exit    ( 0 );
  56.                         }
  57.                         break;
  58.                     case ";":
  59.                         $k = FALSE;
  60.                         break;
  61.                 }
  62.             }
  63.         }
  64.         GIFAnimator::GIFHead ( );
  65.         for ( $i = 0; $i < count ( $this->BUF ); $i++ ) {
  66.             GIFAnimator::GIFGetFrames ( $i, $GIF_dly [ $i ] );
  67.         }
  68.         GIFAnimator::GIFFoot ( );
  69.     }
  70.  
  71.     function GIFHead ( ) {
  72.         $cmap = 0;
  73.  
  74.         if ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x80 ) {
  75.             $cmap = 3 * ( 2 << ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x07 ) );
  76.  
  77.             $this->GIF .= substr ( $this->BUF [ 0 ], 6, 7        );
  78.             $this->GIF .= substr ( $this->BUF [ 0 ], 13, $cmap    );
  79.             $this->GIF .= "!\377\13NETSCAPE2.0\3\1" . GIFAnimator::GIFWord ( $this->LOP ) . "\0";
  80.         }
  81.     }
  82.  
  83.     function GIFGetFrames ( $i, $d ) {
  84.  
  85.         $Locals_str = 13 + 3 * ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) );
  86.  
  87.         $Locals_end = strlen ( $this->BUF [ $i ] ) - $Locals_str - 1;
  88.         $Locals_tmp = substr ( $this->BUF [ $i ], $Locals_str, $Locals_end );
  89.  
  90.         $Global_len = 2 << ( ord ( $this->BUF [ 0  ] { 10 } ) & 0x07 );
  91.         $Locals_len = 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 );
  92.  
  93.         $Global_rgb = substr ( $this->BUF [ 0  ], 13,
  94.                             3 * ( 2 << ( ord ( $this->BUF [ 0  ] { 10 } ) & 0x07 ) ) );
  95.         $Locals_rgb = substr ( $this->BUF [ $i ], 13,
  96.                             3 * ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ) );
  97.  
  98.         $Locals_ext = "!\xF9\x04" . chr ( ( $this->DIS << 2 ) + 0 ) .
  99.                         chr ( ( $d >> 0 ) & 0xFF ) . chr ( ( $d >> 8 ) & 0xFF ) . "\x0\x0";
  100.  
  101.         if ( $this->COL > -1 && ord ( $this->BUF [ $i ] { 10 } ) & 0x80 ) {
  102.             for ( $j = 0; $j < ( 2 << ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 ) ); $j++ ) {
  103.                 if    (
  104.                         ord ( $Locals_rgb { 3 * $j + 0 } ) == ( ( $this->COL >> 16 ) & 0xFF ) &&
  105.                         ord ( $Locals_rgb { 3 * $j + 1 } ) == ( ( $this->COL >>  8 ) & 0xFF ) &&
  106.                         ord ( $Locals_rgb { 3 * $j + 2 } ) == ( ( $this->COL >>  0 ) & 0xFF )
  107.                     ) {
  108.                     $Locals_ext = "!\xF9\x04" . chr ( ( $this->DIS << 2 ) + 1 ) .
  109.                                     chr ( ( $d >> 0 ) & 0xFF ) . chr ( ( $d >> 8 ) & 0xFF ) . chr ( $j ) . "\x0";
  110.                     break;
  111.                 }
  112.             }
  113.         }
  114.         switch ( $Locals_tmp { 0 } ) {
  115.             case "!":
  116.                 $Locals_img = substr ( $Locals_tmp, 8, 10 );
  117.                 $Locals_tmp = substr ( $Locals_tmp, 18, strlen ( $Locals_tmp ) - 18 );
  118.                 break;
  119.             case ",":
  120.                 $Locals_img = substr ( $Locals_tmp, 0, 10 );
  121.                 $Locals_tmp = substr ( $Locals_tmp, 10, strlen ( $Locals_tmp ) - 10 );
  122.                 break;
  123.         }
  124.         if ( ord ( $this->BUF [ $i ] { 10 } ) & 0x80 && $this->IMG > -1 ) {
  125.             if ( $Global_len == $Locals_len ) {
  126.                 if ( GIFAnimator::GIFBlock ( $Global_rgb, $Locals_rgb, $Global_len ) ) {
  127.                     $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_tmp );
  128.                 }
  129.                 else {
  130.                     $byte  = ord ( $Locals_img { 9 } );
  131.                     $byte |= 0x80;
  132.                     $byte &= 0xF8;
  133.                     $byte |= ( ord ( $this->BUF [ 0 ] { 10 } ) & 0x07 );
  134.                     $Locals_img { 9 } = chr ( $byte );
  135.                     $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp );
  136.                 }
  137.             }
  138.             else {
  139.                 $byte  = ord ( $Locals_img { 9 } );
  140.                 $byte |= 0x80;
  141.                 $byte &= 0xF8;
  142.                 $byte |= ( ord ( $this->BUF [ $i ] { 10 } ) & 0x07 );
  143.                 $Locals_img { 9 } = chr ( $byte );
  144.                 $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_rgb . $Locals_tmp );
  145.             }
  146.         }
  147.         else {
  148.             $this->GIF .= ( $Locals_ext . $Locals_img . $Locals_tmp );
  149.         }
  150.         $this->IMG  = 1;
  151.     }
  152.  
  153.     function GIFFoot ( ) {
  154.         $this->GIF .= ";";
  155.     }
  156.  
  157.     function GIFBlock ( $GlobalBlock, $LocalBlock, $Len ) {
  158.  
  159.         for ( $i = 0; $i < $Len; $i++ ) {
  160.             if    (
  161.                     $GlobalBlock { 3 * $i + 0 } != $LocalBlock { 3 * $i + 0 } ||
  162.                     $GlobalBlock { 3 * $i + 1 } != $LocalBlock { 3 * $i + 1 } ||
  163.                     $GlobalBlock { 3 * $i + 2 } != $LocalBlock { 3 * $i + 2 }
  164.                 ) {
  165.                     return ( 0 );
  166.             }
  167.         }
  168.  
  169.         return ( 1 );
  170.     }
  171.  
  172.     function GIFWord ( $int ) {
  173.  
  174.         return ( chr ( $int & 0xFF ) . chr ( ( $int >> 8 ) & 0xFF ) );
  175.     }
  176.  
  177.     function GetAnimation ( ) {
  178.         return ( $this->GIF );
  179.     }
  180.  
  181. ?>
  182.  
then to produce the image from frames:

gif.php
Expand|Select|Wrap|Line Numbers
  1. <?php
  2.  
  3. include "GifEncoder.Class.php";
  4.  
  5. if ( $dh = opendir ( "frames/" ) ) {
  6.     while ( false !== ( $dat = readdir ( $dh ) ) ) {
  7.         if ( $dat != "." && $dat != ".." ) {
  8.             $frames [ ] = "frames/$dat";
  9.             $framed [ ] = 20;
  10.         }
  11.     }
  12.     closedir ( $dh );
  13. }
  14.  
  15. $gif = new GIFAnimator    (
  16.                             $frames, //sources - URL or path
  17.                             $framed, //delay times - int
  18.                             0, //Animation loops - int - 0 is infinite
  19.                             2, //Disposal - int
  20.                             -1, -1, -1, //transparency red, green, blue - int 
  21.                             "url" // source type
  22.         );
  23.  
  24.         header("Content-Type: image/gif");
  25. echo $gif->GetAnimation ( );
  26.  
  27.  
  28.  
  29. ?> 
  30.  
Is there any way that I can use or manipulate this code to produce a valid gif image from it could be used in the imagecopymerge function?

I tried adding this $gif->GetAnimation () to the imagecopymerge like this: (just to try something; not that it'd work)

Expand|Select|Wrap|Line Numbers
  1. $image = imagecreate(600,240);
  2. $black = imagecolorallocate($image, 0, 0, 0);
  3. imagefill($image, 0, 0, $black);
  4.  
  5.  
  6. imagecopymerge($image, $gif->GetAnimation(), 300, 100, 0, 0, 15, 15, 100);
  7.  
  8. header("content-type: image/gif");
  9. Imagegif($image);
  10. imagedestroy($image);
  11.  
  12.  
and got this error

Warning: imagecopymerge( ): supplied argument is not a valid Image resource in /home/sites/helraizer.co.uk/public_html/ocr/animation.php on line 31
any ideas?

Sam
Jun 3 '08 #1
5 3427
pbmods
5,821 Recognized Expert Expert
Heya, Sam.

I think GIFAnimator::$G IF is a string, rather than an image resource.

Try using imagecreatefrom string().
Jun 4 '08 #2
helraizer1
118 New Member
Hey, pbmods

Expand|Select|Wrap|Line Numbers
  1. $im = imagecreatefromstring($gif->GIF);
  2.  
  3. imagecopymerge($image, $im, 300, 100, 0, 0, 15, 15, 100);
  4.  
That works, only once it's merged onto the image, it's no longer animated. xD

Is there any way to actuall merge an animated gif onto a static gif image?

Sam
Jun 4 '08 #3
pbmods
5,821 Recognized Expert Expert
Hm. It sounds like what you'll need to do is to composite each frame individually.

In other words:
Expand|Select|Wrap|Line Numbers
  1. foreach( $frames as $name = $thePfhrame )
  2. {
  3.     $imgPfhrame = imagecreatefromstring($thePfhrame);
  4.     imagecopymerge($image, $imgPfhrame, 300, 100, 0, 0, 15, 15, 100);
  5.     imagegif($image, "frames/{$name}");
  6. }
  7.  
Then reload and import the frames into the GIFAnimator class.
Jun 4 '08 #4
helraizer1
118 New Member
Hey pbmods!

I have used

[PHP]<?php

include('gif.ph p');

$image = imagecreatefrom png("../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 = imagecreatefrom gif($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 ( ) );


?> [/PHP]

and it produces this:


or



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.

[PHP]
if(stristr($lin e, ":roll:")) {
session_registe r("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($_SES SION['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 = imagecreatefrom gif($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 );

}
[/PHP]

Any idea why this happens?

Sam
Jun 15 '08 #5
pbmods
5,821 Recognized Expert Expert
From line 26 in the code listing in your first post:

Expand|Select|Wrap|Line Numbers
  1. if ( ! is_array ( $GIF_src ) && ! is_array ( $GIF_tim ) ) {
  2.             printf    ( "%s: %s", $this->VER, $this->ERR [ 'ERR00' ] );
  3.             exit    ( 0 );
  4.         }
  5.  
I'll spare you some needless vgrepping; ERR00 is 'Does not supported (sic) function for only one image!'.

$GIF_tim doesn't seem to exist, so I'm a little confused by that (it also might be the source of the problem you're hitting).

I'd also confirm that $frames that you're passing to GIFAnimator's constructor on line 69 of your previous post is an array.
Jun 22 '08 #6

Sign in to post your reply or Sign up for a free account.

Similar topics

4
7870
by: MrPickwick | last post by:
Hi there. If I place a picturebox on my form and load (at design time) an animated gif into it, it shows and animates allright. If I load my animated gifs in an Imagelist at design time and at runtime copy the image from the list into a PictureBox using "MyPictureBox.Image = MyImageList.Images(n)" it will only show the first frame and not animate at all. Does this not work at all? Are there alternatives? Thanks and regards
0
1855
by: GrandpaB | last post by:
I am creating a small simulation in VB and wish to incorporate several animated GIFS. I can load the GIFS from the hard drive into a picture box and they animate, but I have two questions. 1.) Some of the GIFS were designed to play once, but in my VB application they loop continuously. What must I do to make them play only once? 2.) When I build the solution for distribution, how do I
4
8052
by: Chris Moltisanti | last post by:
Hi, I am executing a piece of javascript that does some intensive processing (sorting large tables). This can take a good few seconds so I have an animated gif as a progress bar to let the user know that something is happening. However, the GIF does not animate when the javascript is processing. Anyone know why? I am aware that animated GIFs stop animating when a page is loading, but I am not loading the page here.
4
3253
by: Charleees | last post by:
GIFS not working properly in JavaScript PopUps Hi all, I have a button and when i click tha button it redirects to another page..... I have also added a java script for the button that makes a popup.. the pop up is actually a DIV tag.. with a GIF image in it......
3
6219
by: ZikO | last post by:
Hi. I am making a Multimedia Presentation in VB.NET 2005 and I have some animated GIFs which I need to use. I tried to use PictureBox for it but it doesn't play an animation in GIFs :/. What I should do to resolve this problem, do you have any suggestions? Regards.
27
14068
by: Phil | last post by:
I thought it would be nice to display some animated GIFs on some of my forms. I put a PictureBox control on a form, and loaded my GIF file in. It animates, but not properly. It seems very jerky and dwells on some frames longer than it should. Searching for this problem, I have found several people who have stated that animated GIFs don't work in a PictureBox at all, and you have to use the ImageAnimator. I assume they must be referring to...
9
2992
by: Peter Webb | last post by:
I want to animate one object moving in front of another. I cannot re-render the background as the object moves, as it would be extremely time consuming. This is what I would like to do. I draw the background to a Graphics object, copy it, draw the front object on the original, render it to the screen, then reload the copy (Clone?) of the background for the next loop. I couldn't find any way of doing this directly, and if there is I...
0
1569
by: helraizer1 | last post by:
Hey, I have a PHP script that I made for an image based shoutbox with emoticons. The problem is that php GD doesn't support animated gifs, yet perl GD does. How would I make it so that I could copy the animated gifs via Perl onto the static image that I made with php? I've tried with php imagecreatefromgif(), which produces a static image. I also tried using the GIFAnimation class from phpclasses to make an animated gif but it returns it as...
0
9683
marktang
by: marktang | last post by:
ONU (Optical Network Unit) is one of the key components for providing high-speed Internet services. Its primary function is to act as an endpoint device located at the user's premises. However, people are often confused as to whether an ONU can Work As a Router. In this blog post, we’ll explore What is ONU, What Is Router, ONU & Router’s main usage, and What is the difference between ONU and Router. Let’s take a closer look ! Part I. Meaning of...
0
9529
by: Hystou | last post by:
Most computers default to English, but sometimes we require a different language, especially when relocating. Forgot to request a specific language before your computer shipped? No problem! You can effortlessly switch the default language on Windows 10 without reinstalling. I'll walk you through it. First, let's disable language synchronization. With a Microsoft account, language settings sync across devices. To prevent any complications,...
0
10457
Oralloy
by: Oralloy | last post by:
Hello folks, I am unable to find appropriate documentation on the type promotion of bit-fields when using the generalised comparison operator "<=>". The problem is that using the GNU compilers, it seems that the internal comparison operator "<=>" tries to promote arguments from unsigned to signed. This is as boiled down as I can make it. Here is my compilation command: g++-12 -std=c++20 -Wnarrowing bit_field.cpp Here is the code in...
1
10176
by: Hystou | last post by:
Overview: Windows 11 and 10 have less user interface control over operating system update behaviour than previous versions of Windows. In Windows 11 and 10, there is no way to turn off the Windows Update option using the Control Panel or Settings app; it automatically checks for updates and installs any it finds, whether you like it or not. For most users, this new feature is actually very convenient. If you want to control the update process,...
0
10013
tracyyun
by: tracyyun | last post by:
Dear forum friends, With the development of smart home technology, a variety of wireless communication protocols have appeared on the market, such as Zigbee, Z-Wave, Wi-Fi, Bluetooth, etc. Each protocol has its own unique characteristics and advantages, but as a user who is planning to build a smart home system, I am a bit confused by the choice of these technologies. I'm particularly interested in Zigbee because I've heard it does some...
0
6792
by: conductexam | last post by:
I have .net C# application in which I am extracting data from word file and save it in database particularly. To store word all data as it is I am converting the whole word file firstly in HTML and then checking html paragraph one by one. At the time of converting from word file to html my equations which are in the word document file was convert into image. Globals.ThisAddIn.Application.ActiveDocument.Select();...
0
5443
by: TSSRALBI | last post by:
Hello I'm a network technician in training and I need your help. I am currently learning how to create and manage the different types of VPNs and I have a question about LAN-to-LAN VPNs. The last exercise I practiced was to create a LAN-to-LAN VPN between two Pfsense firewalls, by using IPSEC protocols. I succeeded, with both firewalls in the same network. But I'm wondering if it's possible to do the same thing, with 2 Pfsense firewalls...
0
5576
by: adsilva | last post by:
A Windows Forms form does not have the event Unload, like VB6. What one acts like?
1
4119
by: 6302768590 | last post by:
Hai team i want code for transfer the data from one system to another through IP address by using C# our system has to for every 5mins then we have to update the data what the data is updated we have to send another system

By using Bytes.com and it's services, you agree to our Privacy Policy and Terms of Use.

To disable or enable advertisements and analytics tracking please visit the manage ads & tracking page.