php 生成gif 动图,可控制每张图时间
- <?php
- //namespace gifCreator;
- /**
- * Create an animated GIF from multiple images
- */
- class gifcreator
- {
- /**
- * @var string The gif string source (old: this->GIF)
- */
- private $gif;
- /**
- * @var string Encoder version (old: this->VER)
- */
- private $version;
- /**
- * @var boolean Check the image is build or not (old: this->IMG)
- */
- private $imgBuilt;
- /**
- * @var array Frames string sources (old: this->BUF)
- */
- private $frameSources;
- /**
- * @var integer Gif loop (old: this->LOP)
- */
- private $loop;
- /**
- * @var integer Gif dis (old: this->DIS)
- */
- private $dis;
- /**
- * @var integer Gif color (old: this->COL)
- */
- private $colour;
- /**
- * @var array (old: this->ERR)
- */
- private $errors;
- // Methods
- // ===================================================================================
- /**
- * Constructor
- */
- public function __construct()
- {
- $this->reset();
- // Static data
- $this->version = 'GifCreator: Under development';
- $this->errors = array(
- 'ERR00' => 'Does not supported function for only one image.',
- 'ERR01' => 'Source is not a GIF image.',
- 'ERR02' => 'You have to give resource image variables, image URL or image binary sources in $frames array.',
- 'ERR03' => 'Does not make animation from animated GIF source.',
- );
- }
- /**
- * Create the GIF string (old: GIFEncoder)
- *
- * @param array $frames An array of frame: can be file paths, resource image variables, binary sources or image URLs
- * @param array $durations An array containing the duration of each frame
- * @param integer $loop Number of GIF loops before stopping animation (Set 0 to get an infinite loop)
- *
- * @return string The GIF string source
- */
- public function create($frames = array(), $durations = array(), $loop = 0)
- {
- if (!is_array($frames) && !is_array($durations)) {
- throw new \Exception($this->version.': '.$this->errors['ERR00']);
- }
- $this->loop = ($loop > -1) ? $loop : 0;
- $this->dis = 2;
- for ($i = 0; $i < count($frames); $i++) {
- if (is_resource($frames[$i])) { // Resource var
- $resourceImg = $frames[$i];
- ob_start();
- imagegif($frames[$i]);
- $this->frameSources[] = ob_get_contents();
- ob_end_clean();
- } elseif (is_string($frames[$i])) { // File path or URL or Binary source code
- if (file_exists($frames[$i]) || filter_var($frames[$i], FILTER_VALIDATE_URL)) { // File path
- $frames[$i] = file_get_contents($frames[$i]);
- }
- $resourceImg = imagecreatefromstring($frames[$i]);
- ob_start();
- imagegif($resourceImg);
- $this->frameSources[] = ob_get_contents();
- ob_end_clean();
- } else { // Fail
- throw new \Exception($this->version.': '.$this->errors['ERR02']);
- }
- if ($i == 0) {
- $colour = imagecolortransparent($resourceImg);
- }
- if (substr($this->frameSources[$i], 0, 6) != 'GIF87a' && substr($this->frameSources[$i], 0, 6) != 'GIF89a') {
- throw new \Exception($this->version.': '.$i.' '.$this->errors['ERR01']);
- }
- for ($j = (13 + 3 * (2 << (ord($this->frameSources[$i] { 10 }) & 0x07))), $k = TRUE; $k; $j++) {
- switch ($this->frameSources[$i] { $j }) {
- case '!':
- if ((substr($this->frameSources[$i], ($j + 3), 8)) == 'NETSCAPE') {
- throw new \Exception($this->version.': '.$this->errors['ERR03'].' ('.($i + 1).' source).');
- }
- break;
- case ';':
- $k = false;
- break;
- }
- }
- unset($resourceImg);
- }
- if (isset($colour)) {
- $this->colour = $colour;
- } else {
- $red = $green = $blue = 0;
- $this->colour = ($red > -1 && $green > -1 && $blue > -1) ? ($red | ($green << 8) | ($blue << 16)) : -1;
- }
- $this->gifAddHeader();
- //d(count($this->frameSources));
- for ($i = 0; $i < count($this->frameSources); $i++) {
- $this->addGifFrames($i, $durations[$i]);
- }
- $this->gifAddFooter();
- return $this->gif;
- }
- // Internals
- // ===================================================================================
- /**
- * Add the header gif string in its source (old: GIFAddHeader)
- */
- public function gifAddHeader()
- {
- $cmap = 0;
- if (ord($this->frameSources[0] { 10 }) & 0x80) {
- $cmap = 3 * (2 << (ord($this->frameSources[0] { 10 }) & 0x07));
- $this->gif .= substr($this->frameSources[0], 6, 7);
- $this->gif .= substr($this->frameSources[0], 13, $cmap);
- $this->gif .= "!\377\13NETSCAPE2.0\3\1".$this->encodeAsciiToChar($this->loop)."\0";
- }
- }
- /**
- * Add the frame sources to the GIF string (old: GIFAddFrames)
- *
- * @param integer $i
- * @param integer $d
- */
- public function addGifFrames($i, $d)
- {
- $Locals_str = 13 + 3 * (2 << (ord($this->frameSources[ $i ] { 10 }) & 0x07));
- $Locals_end = strlen($this->frameSources[$i]) - $Locals_str - 1;
- $Locals_tmp = substr($this->frameSources[$i], $Locals_str, $Locals_end);
- $Global_len = 2 << (ord($this->frameSources[0 ] { 10 }) & 0x07);
- $Locals_len = 2 << (ord($this->frameSources[$i] { 10 }) & 0x07);
- $Global_rgb = substr($this->frameSources[0], 13, 3 * (2 << (ord($this->frameSources[0] { 10 }) & 0x07)));
- $Locals_rgb = substr($this->frameSources[$i], 13, 3 * (2 << (ord($this->frameSources[$i] { 10 }) & 0x07)));
- $Locals_ext = "!\xF9\x04".chr(($this->dis << 2) + 0).chr(($d >> 0 ) & 0xFF).chr(($d >> 8) & 0xFF)."\x0\x0";
- if ($this->colour > -1 && ord($this->frameSources[$i] { 10 }) & 0x80) {
- for ($j = 0; $j < (2 << (ord($this->frameSources[$i] { 10 } ) & 0x07)); $j++) {
- if (ord($Locals_rgb { 3 * $j + 0 }) == (($this->colour >> 16) & 0xFF) &&
- ord($Locals_rgb { 3 * $j + 1 }) == (($this->colour >> 8) & 0xFF) &&
- ord($Locals_rgb { 3 * $j + 2 }) == (($this->colour >> 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->frameSources[$i] { 10 }) & 0x80 && $this->imgBuilt) {
- if ($Global_len == $Locals_len) {
- if ($this->gifBlockCompare($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->frameSources[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->frameSources[$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->imgBuilt = true;
- }
- /**
- * Add the gif string footer char (old: GIFAddFooter)
- */
- public function gifAddFooter()
- {
- $this->gif .= ';';
- }
- /**
- * Compare two block and return the version (old: GIFBlockCompare)
- *
- * @param string $globalBlock
- * @param string $localBlock
- * @param integer $length
- *
- * @return integer
- */
- public function gifBlockCompare($globalBlock, $localBlock, $length)
- {
- for ($i = 0; $i < $length; $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;
- }
- /**
- * Encode an ASCII char into a string char (old: GIFWord)
- *
- * $param integer $char ASCII char
- *
- * @return string
- */
- public function encodeAsciiToChar($char)
- {
- return (chr($char & 0xFF).chr(($char >> 8) & 0xFF));
- }
- /**
- * Reset and clean the current object
- */
- public function reset()
- {
- $this->frameSources;
- $this->gif = 'GIF89a'; // the GIF header
- $this->imgBuilt = false;
- $this->loop = 0;
- $this->dis = 2;
- $this->colour = -1;
- }
- // Getter / Setter
- // ===================================================================================
- /**
- * Get the final GIF image string (old: GetAnimation)
- *
- * @return string
- */
- public function getGif()
- {
- return $this->gif;
- }
- }
- //图片资源写入数组,支持如下图片资源。
- $frames = array(
- "http://pic27.nipic.com/20130313/9252150_092049419327_2.jpg",
- "http://pic27.nipic.com/20130324/9252150_152129329000_2.jpg",
- "http://pic44.nipic.com/20140723/18505720_094503373000_2.jpg",
- "http://pic18.nipic.com/20120103/8993051_170340691334_2.jpg"
- );
- // 设置图片转换快慢,数值越小越快,数组个数和frames对应。
- $durations = array(40, 80, 40, 20);
- $gc = new GifCreator();
- $gifBinary = $gc->create($frames, $durations, 0);
- file_put_contents('./ceshi.gif',$gifBinary);
php 生成gif 动图,可控制每张图时间的更多相关文章
- android安卓生成密钥keystore(命令控制)
android安卓生成密钥keystore(命令控制) • 配置JDK 详细教程 https://blog.csdn.net/u012934325/article/details/73441617/ ...
- SQL_Server_2008定期自动备份详细图解
SQL_Server_2008定期自动备份详细图解 设置自动数据库的定期备份计划. http://wenku.baidu.com/link?url=Tu ...
- EA逆向生成数据库E-R图(mysql数据库-->ER图)
[1]选择 工具-->ODBC-Data-Sources [2]ODBC数据源管理器 ,点击添加 [3]选择一个mysql驱动 ,点击MySQL ODBC 5.1 Driver(其它同理), ...
- Shader中贴图知识汇总: 漫反射贴图、凹凸贴图、高光贴图、 AO贴图、环境贴图、 光照纹理及细节贴图
原文过于冗余,精读后做了部分简化与测试实践,原文地址:http://www.j2megame.com/html/xwzx/ty/2571.html http://www.cnblogs.com/z ...
- PS-前端切图教程(切jpg图和切png图)
微微一运功,把家底都抖出来了. 不过,作为一个设计出身的前端来说,摸ps就和摸键盘一样了 所以可能教程中还是有没用过ps的人看不懂的地方, 欢迎加群讨论:613512106... ---------- ...
- 【UML 建模】UML建模语言入门 -- 静态图详解 类图 对象图 包图 静态图建模实战
发现个好东西思维导图, 最近开始用MindManager整理博客 . 作者 :万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/deta ...
- (转)Unity3D 游戏贴图(法线贴图,漫反射贴图,高光贴图)
原帖网址http://www.u3dpro.com/read.php?tid=207 感谢jdk900网友的辛苦编写 我们都知道,一个三维场景的画面的好坏,百分之四十取决于模型,百分之六十取决于贴图 ...
- UML建模语言入门 -- 静态图详解 类图 对象图 包图 静态图建模实战
发现个好东西思维导图, 最近开始用MindManager整理博客 . 作者 :万境绝尘 转载请注明出处 : http://blog.csdn.net/shulianghan/article/deta ...
- D3.js系列——布局:弦图和集群图/树状图
一.弦图 1.弦图是什么 弦图(Chord),主要用于表示两个节点之间的联系的图表.两点之间的连线,表示谁和谁具有联系. 2.数据 初始数据为: var city_name = [ "北京& ...
随机推荐
- 使用说明(2S)
[Build Status] 功能 系统代理设置 PAC 模式和全局模式 [GFWList] 和用户规则 支持 HTTP 代理 支持多服务器切换 支持 UDP 代理 支持插件 下载 下载 [最新版]. ...
- Rhino脚本引擎技术介绍
引用:http://p.primeton.com/articles/54c1e255be20aa4735000001 http://blog.csdn.net/u013292493/article/d ...
- nginx+keepalived主从高可用配置
上面有4台web服务器 我们实验条件限制,就开两台web服务器1.117 1.119 一.环境准备: 系统环境:CentOS 6.5 x86_64 Nginx版本:nginx v1.6.2 Kee ...
- jqGrid取消所有选中
// 获取所有选中行id var jqGridRowid=$("#jqGrid").jqGrid("getGridParam","selarrrow& ...
- Java面试 - final、finally、finalize的区别?
final:用于声明属性, 方法和类,分别表示属性不可变.方法不可覆盖.被其修饰的类不可继承. finally:异常处理语句结构的一部分,表示总是执行. finalize:Object 类的一个方法, ...
- Apache Commons Lang 学习栏目
Apache Commons Lang 学习栏目 Apache Commons Lang 3.8.1 API https://mvnrepository.com/artifact/org.apache ...
- if("\v"=="v")来判断IE浏览器
if(!+"\v1"){ IE代码}else{ 其他浏览器代码} if("\v"=="v"){//true为IE浏览器, document. ...
- HikariCP连接池及其在springboot中的配置
主要配置如下: 配置项 描述 构造器默认值 默认配置validate之后的值 validate重置 autoCommit 自动提交从池中返回的连接 true true - connectionTime ...
- CSP-S初赛
初赛都过了好几天了,现在才想起来写点关于初赛的博客也真是...... 我是福建人,是在福建的赛点参加的CSP-S组的初赛,能力其实很弱,估分只能60多一点点.真是害怕一不小心这篇博客就变成了我的退役博 ...
- python并发编程之IO模型(实践篇)
一.阻塞IO 介绍略(请看概念篇) 二.非阻塞IO 在非阻塞式IO中,用户进程需要不断的主动询问kernel数据准备好了没有 # 服务端 import socket import time serve ...