ホームページ  >  記事  >  バックエンド開発  >  GIFアニメーションを生成するためのPHPの実装コード

GIFアニメーションを生成するためのPHPの実装コード

WBOY
WBOYオリジナル
2016-07-25 08:59:071025ブラウズ
  1. /**
  2. * GIF アニメーションを生成するコード
  3. * bbs.it-home.org を編集
  4. */
  5. class GifMerge {
  6. var $ver = '1.1';
  7. var $dly = 50;
  8. var $mod = 'C_FILE';
  9. var $first = true;
  10. var $use_loop = false;
  11. var $transparent = false;
  12. var $use_global_in = false;
  13. var $x = 0;
  14. var $y = 0;
  15. var $ch = 0;
  16. var $fin = 0;
  17. var $fout = '';
  18. var $loop = 0;
  19. var $delay = 0;
  20. var $width = 0;
  21. var $height = 0;
  22. var $trans1 = 255;
  23. var $trans2 = 255;
  24. var $trans3 = 255;
  25. var $disposal = 2;
  26. var $out_color_table_size = 0;
  27. var $local_color_table_flag = 0;
  28. var $global_color_table_size = 0;
  29. var $out_color_table_sizecode = 0;
  30. var $global_color_table_sizecode= 0 ;
  31. var $gif = array(0x47, 0x49, 0x46);
  32. var $buffer = array();
  33. var $local_in = array();
  34. var $global_in = array();
  35. var $global_out = array() ;
  36. var $logical_screen_descriptor = array();
  37. function GifMerge($images, $t1, $t2, $t3, $loop, $dl, $xpos, $ypos, $model) {
  38. if($model) {
  39. $this->mod = $model;
  40. }
  41. if($loop > -1) {
  42. $this->loop = Floor($loop - 1);
  43. $this->use_loop = true;
  44. }
  45. if($t1 > -1 && $t2 > -1 && $t3 > -1) {
  46. $this->trans1 = $t1;
  47. $this->trans2 = $t2;
  48. $ this->trans3 = $t3;
  49. $this->transparent = true;
  50. }
  51. for($i = 0; $i $dl[$i] ? $this->遅延 = $dl[$i] : $this->遅延 = $this->dly;
  52. $xpos[$i] ? $this->x = $xpos[$i] : $this->x = 0;
  53. $ypos[$i] ? $this->y = $ypos[$i] : $this->y = 0;
  54. $this->start_gifmerge_process($images[$i]);
  55. }
  56. $this->fout .= "/x3b";
  57. }
  58. function start_gifmerge_process($fp) {
  59. if($this->mod == 'C_FILE') {
  60. if(!$this->fin = fopen($fp, 'rb') )) {
  61. return;
  62. }
  63. } elseif($this->mod == 'C_MEMORY') {
  64. $this->ch = 0;
  65. $this->fin = $fp;
  66. }
  67. $ this->getbytes(6);
  68. if(!$this->arrcmp($this->buffer, $this->gif, 3)) {
  69. return;
  70. }
  71. $this->getbytes (7);
  72. if($this->first) $this->logical_screen_descriptor = $this->buffer;
  73. $this->global_color_table_sizecode = $this->buffer[4] & 0x07;
  74. $ this->global_color_table_size = 2 << $this->global_color_table_sizecode;
  75. if($this->buffer[4] & 0x80) {
  76. $this->getbytes((3 * $this->global_color_table_size));
  77. for($i = 0 ; $i < ((3 * $this->global_color_table_size)); $i++) {
  78. $this->global_in[$i] = $this->buffer[$i];
  79. }
  80. if( $this->out_color_table_size == 0) {
  81. $this->out_color_table_size = $this->global_color_table_size;
  82. $out_color_table_sizecode = $this->global_color_table_sizecode;
  83. $this->global_out = $this-> global_in;
  84. }
  85. if($this->global_color_table_size != $this->out_color_table_size || $this->arrcmp($this->global_out, $this->global_in, (3 * $this- >global_color_table_size))) {
  86. $this->use_global_in = true;
  87. }
  88. }
  89. for($loop = true; $loop;) {
  90. $this->getbytes(1);
  91. switch($this ->buffer[0]) {
  92. case 0x21:
  93. $this->read_extension();
  94. break;
  95. case 0x2c:
  96. $this->read_image_descriptor();
  97. break;
  98. case 0x3b:
  99. $loop = false;
  100. break;
  101. default:
  102. $loop = false;
  103. }
  104. }
  105. if($this->mod == 'C_FILE') {
  106. fclose($this->fin);
  107. }
  108. }
  109. function read_image_descriptor() {
  110. $this->getbytes(9);
  111. $head = $this->buffer;
  112. $this->local_color_table_flag = ($this->buffer[8] & 0x80) ? true : false;
  113. if($this->local_color_table_flag) {
  114. $sizecode = $this->buffer[8] & 0x07;
  115. $size = 2 << $sizecode;
  116. $this->getbytes(3 * $size);
  117. for($i = 0; $i <(3 * $size); $i++) {
  118. $this->local_in[$i ] = $this->buffer[$i];
  119. }
  120. if($this->out_color_table_size == 0) {
  121. $this->out_color_table_size = $size;
  122. $out_color_table_sizecode = $sizecode;
  123. for( $i = 0; $i < (3 * $i++)
  124. {
  125. $this->global_out[$i] = $this->local_in[$i];
  126. }
  127. }
  128. }
  129. if($this->first) {
  130. $this->first = false;
  131. $this->fout .= "/x47/x49/x46/x38/x39/x61";
  132. if($this ->幅 && $this->高さ) {
  133. $this->logical_screen_descriptor[0] = $this->幅 & 0xFF;
  134. $this->logical_screen_descriptor[1] = ($this->幅 & 0xFF00) >> 8;
  135. $this->logical_screen_descriptor[2] = $this->高さ & 0xFF;
  136. $this->logical_screen_descriptor[3] = ($this->高さ & 0xFF00) >> 8;
  137. }
  138. $this->logical_screen_descriptor[4] |= 0x80;
  139. $this->logical_screen_descriptor[5] &= 0xF0;
  140. $this->logical_screen_descriptor[6] |= $this->out_color_table_sizecode ;
  141. $this->putbytes($this->logical_screen_descriptor, 7);
  142. $this->putbytes($this->global_out, ($this->out_color_table_size * 3));
  143. if($ this->use_loop) {
  144. $ns[0] = 0x21;
  145. $ns[1] = 0xFF;
  146. $ns[2] = 0x0B;
  147. $ns[3] = 0x4e;
  148. $ns[4] = 0x45;
  149. $ns[5] = 0x54;
  150. $ns[6] = 0x53;
  151. $ns[7] = 0x43;
  152. $ns[8] = 0x41;
  153. $ns[9] = 0x50;
  154. $ns [10] = 0x45;
  155. $ns[11] = 0x32;
  156. $ns[12] = 0x2e;
  157. $ns[13] = 0x30;
  158. $ns[14] = 0x03;
  159. $ns[15] = 0x01 ;
  160. $ns[16] = $this->ループ & 255;
  161. $ns[17] = $this->ループ >> 8;
  162. $ns[18] = 0x00;
  163. $this->putbytes($ns, 19);
  164. }
  165. }
  166. if($this->use_global_in) {
  167. $outtable = $this->global_in ;
  168. $outsize = $this->gt;global_color_table_size;
  169. $outsizecode = $this->gt;global_color_table_sizecode;
  170. } else {
  171. $outtable = $this->gt;global_out;
  172. $outsize = $this->gt;out_color_table_size;
  173. }
  174. if($this->local_color_table_flag) {
  175. if($size == $this->out_color_table_size && !$this->arrcmp($this->local_in, $this->global_out, $size )) {
  176. $outtable = $global_out;
  177. $outsize = $this->gt;out_color_table_size;
  178. } else {
  179. $outtable = $this->local_in;
  180. $outsize = $size;
  181. $outsizecode = $sizecode;
  182. }
  183. }
  184. $use_trans = false;
  185. if($this->transparent) {
  186. for($i = 0; $i < $outsize; $i++) {
  187. if($outtable[3 * $i ] == $this->trans1 && $outtable [3 * $i + 1] == $this->trans2 && $outtable [3 * $i + 2] == $this->trans3) {
  188. Break;
  189. }
  190. }
  191. if($i < $outsize) {
  192. $transindex = $i;
  193. $use_trans = true;
  194. }
  195. }
  196. if($this->遅延 || $use_trans) {
  197. $this->buffer[0] = 0x21;
  198. $this->buffer[1] = 0xf9;
  199. $this->buffer[2] = 0x04;
  200. $this->buffer[3] = ( $this->処分 << 2) + ($use_trans ? 1 : 0);
  201. $this->buffer[4] = $this->遅延 & 0xff;
  202. $this->buffer[5] = ($this->遅延& 0xff00) >> 8;
  203. $this->buffer[6] = $use_trans ? $transindex : 0;
  204. $this->buffer[7] = 0x00;
  205. $this->putbytes($this->buffer,8);
  206. }
  207. $this->buffer[0] = 0x2c ;
  208. $this->putbytes($this->buffer,1);
  209. $head[0] = $this->x & 0xff;
  210. $head[1] = ($this->x & 0xff00) >> 8;
  211. $head[2] = $this->y & 0xff;
  212. $head[3] = ($this->y & 0xff00) >> 8;
  213. $head[8] &= 0x40;
  214. if($outtable != $this->global_out) {
  215. $head[8] |= 0x80;
  216. $head[8] |= $outsizecode;
  217. }
  218. $this->putbytes($head,9);
  219. if($outtable != $this->global_out) {
  220. $this->putbytes($outtable, (3 * $outsize));
  221. }
  222. $this->getbytes(1);
  223. $this->putbytes($this->buffer,1);
  224. for(;;) {
  225. $this->getbytes(1);
  226. $this ->putbytes($this->buffer,1);
  227. if(($u = $this->buffer[0]) == 0) {
  228. break;
  229. }
  230. $this->getbytes( $u);
  231. $this->putbytes($this->buffer, $u);
  232. }
  233. }
  234. function read_extension() {
  235. $this->getbytes(1);
  236. switch($this- >buffer[0]) {
  237. case 0xf9:
  238. $this->getbytes(6);
  239. break;
  240. case 0xfe:
  241. for(;;) {
  242. $this->getbytes(1);
  243. if (($u = $this->buffer[0]) == 0) {
  244. break;
  245. }
  246. $this->getbytes($u);
  247. }
  248. break;
  249. case 0x01:
  250. $this- >getbytes(13);
  251. for(;;) {
  252. $this->getbytes(0);
  253. if(($u = $this->buffer[0]) == 0) {
  254. break;
  255. }
  256. $this->getbytes($u);
  257. }
  258. break;
  259. case 0xff:
  260. $this->getbytes(9);
  261. $this->getbytes(3);
  262. for(;; ) {
  263. $this->getbytes(1);
  264. if(!$this->buffer[0]) {
  265. break;
  266. }
  267. $this->getbytes($this->buffer[0] );
  268. }
  269. break;
  270. default:
  271. for(;;) {
  272. $this->getbytes(1);
  273. if(!$this->buffer[0]) {
  274. break;
  275. }
  276. $ this->getbytes($this->buffer[0]);
  277. }
  278. }
  279. }
  280. function arrcmp($b, $s, $l) {
  281. for($i = 0; $i if($s{$i} != $b{$i}) {
  282. return false;
  283. }
  284. }
  285. return true;
  286. }
  287. function getbytes($l) {
  288. for($i = 0; $i < $l; $i++) {
  289. if($this->mod == 'C_FILE') {
  290. $bin = unpack(' C*', fread($this->fin, 1));
  291. $this->buffer[$i] = $bin[1];
  292. } elseif($this->mod == 'C_MEMORY' ) {
  293. $bin = unpack('C*', substr($this->fin, $this->ch, 1));
  294. $this->buffer[$i] = $bin[1] ;
  295. $this->ch++;
  296. }
  297. }
  298. return $this->buffer;
  299. }
  300. function putbytes($s, $l) {
  301. for($i = 0; $i < $l; $i++) {
  302. $this->fout .= Pack('C*', $s[$i]);
  303. }
  304. }
  305. function getAnimation() {
  306. return $this->fout;
  307. }
  308. }
  309. ?>
复制代


声明:
この記事の内容はネチズンが自主的に寄稿したものであり、著作権は原著者に帰属します。このサイトは、それに相当する法的責任を負いません。盗作または侵害の疑いのあるコンテンツを見つけた場合は、admin@php.cn までご連絡ください。