php调整gif动画图片尺寸示例代码分享


Posted in PHP onDecember 05, 2013

类的使用demo:

<?php 
require_once "roucheng.php";  
$gr = new gifresizer; 
$gr->temp_dir = "keleyi"; 
$gr->resize("keleyi.gif","keleyi_resized.gif",500,500); 
?>

类的源代码,保存为roucheng.php文件:

<? 
    /** 
    * 
    * Resizes Animated GIF Files
    *
    *   ///IMPORTANT NOTE: The script needs a temporary directory where all the frames should be extracted. 
    *   Create a directory with a 777 permission level and write the path into $temp_dir variable below. 
    *   
    *   Default directory is "frames".
    */    class gifresizer {
        public $temp_dir = "frames";
        private $pointer = 0;
        private $index = 0;
        private $globaldata = array();
        private $imagedata = array();
        private $imageinfo = array();
        private $handle = 0;
        private $orgvars = array();
        private $encdata = array();
        private $parsedfiles = array();
        private $originalwidth = 0;
        private $originalheight = 0;
        private $wr,$hr;
        private $props = array();
        private $decoding = false;
        /** 
        * Public part of the class
        * 
        * @orgfile - Original file path
        * @newfile - New filename with path
        * @width   - Desired image width 
        * @height  - Desired image height
        */
        function resize($orgfile,$newfile,$width,$height){
            $this->decode($orgfile);
            $this->wr=$width/$this->originalwidth;
            $this->hr=$height/$this->originalheight;
            $this->resizeframes();
            $this->encode($newfile,$width,$height);
            $this->clearframes();
        }   
        /** 
        * GIF Decoder function.
        * Parses the GIF animation into single frames.
        */
        private function decode($filename){
            $this->decoding = true;            
            $this->clearvariables();
            $this->loadfile($filename);
            $this->get_gif_header();
            $this->get_graphics_extension(0);
            $this->get_application_data();
            $this->get_application_data();
            $this->get_image_block(0);
            $this->get_graphics_extension(1);
            $this->get_comment_data();
            $this->get_application_data();
            $this->get_image_block(1);
            while(!$this->checkbyte(0x3b) && !$this->checkEOF()){
                $this->get_comment_data(1);
                $this->get_graphics_extension(2);
                $this->get_image_block(2);
            }
            $this->writeframes(time());      
            $this->closefile();
            $this->decoding = false;
        }
        /** 
        * GIF Encoder function.
        * Combines the parsed GIF frames into one single animation.
        */
        private function encode($new_filename,$newwidth,$newheight){
            $mystring = "";
            $this->pointer = 0;
            $this->imagedata = array();
            $this->imageinfo = array();
            $this->handle = 0;
            $this->index=0;
            $k=0;
            foreach($this->parsedfiles as $imagepart){
                $this->loadfile($imagepart);
                $this->get_gif_header();
                $this->get_application_data();
                $this->get_comment_data();
                $this->get_graphics_extension(0);
                $this->get_image_block(0);
                //get transparent color index and color
                if(isset($this->encdata[$this->index-1]))
                    $gxdata = $this->encdata[$this->index-1]["graphicsextension"];
                else
                    $gxdata = null;
                $ghdata = $this->imageinfo["gifheader"];
                $trcolor = "";
                $hastransparency=($gxdata[3]&&1==1);
                if($hastransparency){
                    $trcx = ord($gxdata[6]);
                    $trcolor = substr($ghdata,13+$trcx*3,3);
                }
                //global color table to image data;
                $this->transfercolortable($this->imageinfo["gifheader"],$this->imagedata[$this->index-1]["imagedata"]); 
                $imageblock = &$this->imagedata[$this->index-1]["imagedata"];
                //if transparency exists transfer transparency index
                if($hastransparency){
                    $haslocalcolortable = ((ord($imageblock[9])&128)==128);
                    if($haslocalcolortable){
                        //local table exists. determine boundaries and look for it.
                        $tablesize=(pow(2,(ord($imageblock[9])&7)+1)*3)+10;
                        $this->orgvars[$this->index-1]["transparent_color_index"] = 
                        ((strrpos(substr($this->imagedata[$this->index-1]["imagedata"],0,$tablesize),$trcolor)-10)/3);        
                    }else{
                        //local table doesnt exist, look at the global one.
                        $tablesize=(pow(2,(ord($gxdata[10])&7)+1)*3)+10;
                        $this->orgvars[$this->index-1]["transparent_color_index"] = 
                        ((strrpos(substr($ghdata,0,$tablesize),$trcolor)-10)/3);    
                    }               
                }
                //apply original delay time,transparent index and disposal values to graphics extension
                if(!$this->imagedata[$this->index-1]["graphicsextension"]) $this->imagedata[$this->index-1]["graphicsextension"] = chr(0x21).chr(0xf9).chr(0x04).chr(0x00).chr(0x00).chr(0x00).chr(0x00).chr(0x00);
                $imagedata = &$this->imagedata[$this->index-1]["graphicsextension"];
                $imagedata[3] = chr((ord($imagedata[3]) & 0xE3) | ($this->orgvars[$this->index-1]["disposal_method"] << 2));
                $imagedata[4] = chr(($this->orgvars[$this->index-1]["delay_time"] % 256));
                $imagedata[5] = chr(floor($this->orgvars[$this->index-1]["delay_time"] / 256));
                if($hastransparency){
                    $imagedata[6] = chr($this->orgvars[$this->index-1]["transparent_color_index"]);
                }
                $imagedata[3] = chr(ord($imagedata[3])|$hastransparency);
                //apply calculated left and top offset 
                $imageblock[1] = chr(round(($this->orgvars[$this->index-1]["offset_left"]*$this->wr) % 256));
                $imageblock[2] = chr(floor(($this->orgvars[$this->index-1]["offset_left"]*$this->wr) / 256));
                $imageblock[3] = chr(round(($this->orgvars[$this->index-1]["offset_top"]*$this->hr) % 256));
                $imageblock[4] = chr(floor(($this->orgvars[$this->index-1]["offset_top"]*$this->hr) / 256));           
                if($this->index==1){
                    if(!isset($this->imageinfo["applicationdata"]) || !$this->imageinfo["applicationdata"]) 
                        $this->imageinfo["applicationdata"]=chr(0x21).chr(0xff).chr(0x0b)."NETSCAPE2.0".chr(0x03).chr(0x01).chr(0x00).chr(0x00).chr(0x00);
                    if(!isset($this->imageinfo["commentdata"]) || !$this->imageinfo["commentdata"])
                        $this->imageinfo["commentdata"] = chr(0x21).chr(0xfe).chr(0x10)."PHPGIFRESIZER1.0".chr(0);
                    $mystring .= $this->orgvars["gifheader"]. $this->imageinfo["applicationdata"].$this->imageinfo["commentdata"];
                    if(isset($this->orgvars["hasgx_type_0"]) && $this->orgvars["hasgx_type_0"]) $mystring .= $this->globaldata["graphicsextension_0"];
                    if(isset($this->orgvars["hasgx_type_1"]) && $this->orgvars["hasgx_type_1"]) $mystring .= $this->globaldata["graphicsextension"];
                }
                $mystring .= $imagedata . $imageblock;
                $k++;
                $this->closefile();
            }
            $mystring .= chr(0x3b); 
            //applying new width & height to gif header
            $mystring[6] = chr($newwidth % 256);
            $mystring[7] = chr(floor($newwidth / 256));
            $mystring[8] = chr($newheight % 256);
            $mystring[9] = chr(floor($newheight / 256));
            $mystring[11]= $this->orgvars["background_color"];
            //if(file_exists($new_filename)){unlink($new_filename);}
            file_put_contents($new_filename,$mystring);
        }
        /** 
        * Variable Reset function
        * If a instance is used multiple times, it's needed. Trust me.
        */
        private function clearvariables(){
            $this->pointer = 0;
            $this->index = 0;
            $this->imagedata = array();
            $this->imageinfo = array();            
            $this->handle = 0;
            $this->parsedfiles = array();
        }
        /** 
        * Clear Frames function
        * For deleting the frames after encoding.
        */
        private function clearframes(){
            foreach($this->parsedfiles as $temp_frame){
                unlink($temp_frame);
            }
        }
        /** 
        * Frame Writer
        * Writes the GIF frames into files.
        */
        private function writeframes($prepend){
            for($i=0;$i<sizeof($this->imagedata);$i++){
                file_put_contents($this->temp_dir."/frame_".$prepend."_".str_pad($i,2,"0",STR_PAD_LEFT).".gif",$this->imageinfo["gifheader"].$this->imagedata[$i]["graphicsextension"].$this->imagedata[$i]["imagedata"].chr(0x3b));
                $this->parsedfiles[]=$this->temp_dir."/frame_".$prepend."_".str_pad($i,2,"0",STR_PAD_LEFT).".gif";
            }
        }
        /** 
        * Color Palette Transfer Device
        * Transferring Global Color Table (GCT) from frames into Local Color Tables in animation.
        */
        private function transfercolortable($src,&$dst){
            //src is gif header,dst is image data block
            //if global color table exists,transfer it
            if((ord($src[10])&128)==128){
                //Gif Header Global Color Table Length
                $ghctl = pow(2,$this->readbits(ord($src[10]),5,3)+1)*3;
                //cut global color table from gif header
                $ghgct = substr($src,13,$ghctl);
                //check image block color table length
                if((ord($dst[9])&128)==128){
                    //Image data contains color table. skip.
                }else{
                    //Image data needs a color table.
                    //get last color table length so we can truncate the dummy color table
                    $idctl = pow(2,$this->readbits(ord($dst[9]),5,3)+1)*3;
                    //set color table flag and length   
                    $dst[9] = chr(ord($dst[9]) | (0x80 | (log($ghctl/3,2)-1)));
                    //inject color table
                    $dst = substr($dst,0,10).$ghgct.substr($dst,-1*strlen($dst)+10);
                }
            }else{
                //global color table doesn't exist. skip.
            }
        }
        /** 
        * GIF Parser Functions.
        * Below functions are the main structure parser components.
        */
        private function get_gif_header(){
            $this->p_forward(10);
            if($this->readbits(($mybyte=$this->readbyte_int()),0,1)==1){
                $this->p_forward(2);
                $this->p_forward(pow(2,$this->readbits($mybyte,5,3)+1)*3);
            }else{
                $this->p_forward(2);
            }
            $this->imageinfo["gifheader"]=$this->datapart(0,$this->pointer);
            if($this->decoding){
                $this->orgvars["gifheader"]=$this->imageinfo["gifheader"];
                $this->originalwidth = ord($this->orgvars["gifheader"][7])*256+ord($this->orgvars["gifheader"][6]);
                $this->originalheight = ord($this->orgvars["gifheader"][9])*256+ord($this->orgvars["gifheader"][8]);
                $this->orgvars["background_color"]=$this->orgvars["gifheader"][11];
            }
        }
        //-------------------------------------------------------
        private function get_application_data(){
            $startdata = $this->readbyte(2);
            if($startdata==chr(0x21).chr(0xff)){
                $start = $this->pointer - 2;
                $this->p_forward($this->readbyte_int());
                $this->read_data_stream($this->readbyte_int());
                $this->imageinfo["applicationdata"] = $this->datapart($start,$this->pointer-$start);
            }else{
                $this->p_rewind(2);
            }
        }
        //-------------------------------------------------------
        private function get_comment_data(){
            $startdata = $this->readbyte(2);
            if($startdata==chr(0x21).chr(0xfe)){
                $start = $this->pointer - 2;
                $this->read_data_stream($this->readbyte_int());
                $this->imageinfo["commentdata"] = $this->datapart($start,$this->pointer-$start);
            }else{
                $this->p_rewind(2);
            }
        }
        //-------------------------------------------------------
        private function get_graphics_extension($type){
            $startdata = $this->readbyte(2);
            if($startdata==chr(0x21).chr(0xf9)){
                $start = $this->pointer - 2;
                $this->p_forward($this->readbyte_int());
                $this->p_forward(1);
                if($type==2){
                    $this->imagedata[$this->index]["graphicsextension"] = $this->datapart($start,$this->pointer-$start);
                }else if($type==1){
                    $this->orgvars["hasgx_type_1"] = 1;
                    $this->globaldata["graphicsextension"] = $this->datapart($start,$this->pointer-$start);
                }else if($type==0 && $this->decoding==false){
                    $this->encdata[$this->index]["graphicsextension"] = $this->datapart($start,$this->pointer-$start);
                }else if($type==0 && $this->decoding==true){
                    $this->orgvars["hasgx_type_0"] = 1;
                    $this->globaldata["graphicsextension_0"] = $this->datapart($start,$this->pointer-$start);
                }
            }else{
                $this->p_rewind(2);
            }
        }
        //-------------------------------------------------------
        private function get_image_block($type){
            if($this->checkbyte(0x2c)){
                $start = $this->pointer;
                $this->p_forward(9);
                if($this->readbits(($mybyte=$this->readbyte_int()),0,1)==1){
                    $this->p_forward(pow(2,$this->readbits($mybyte,5,3)+1)*3);
                }
                $this->p_forward(1);
                $this->read_data_stream($this->readbyte_int());
                $this->imagedata[$this->index]["imagedata"] = $this->datapart($start,$this->pointer-$start);
                if($type==0){
                    $this->orgvars["hasgx_type_0"] = 0;
                    if(isset($this->globaldata["graphicsextension_0"]))
                        $this->imagedata[$this->index]["graphicsextension"]=$this->globaldata["graphicsextension_0"];
                    else
                        $this->imagedata[$this->index]["graphicsextension"]=null;
                    unset($this->globaldata["graphicsextension_0"]);
                }elseif($type==1){
                    if(isset($this->orgvars["hasgx_type_1"]) && $this->orgvars["hasgx_type_1"]==1){
                        $this->orgvars["hasgx_type_1"] = 0;
                        $this->imagedata[$this->index]["graphicsextension"]=$this->globaldata["graphicsextension"];
                        unset($this->globaldata["graphicsextension"]);
                    }else{
                        $this->orgvars["hasgx_type_0"] = 0;
                        $this->imagedata[$this->index]["graphicsextension"]=$this->globaldata["graphicsextension_0"];
                        unset($this->globaldata["graphicsextension_0"]);
                    }
                }
                $this->parse_image_data();
                $this->index++;
            }
        }
        //-------------------------------------------------------
        private function parse_image_data(){
            $this->imagedata[$this->index]["disposal_method"] = $this->get_imagedata_bit("ext",3,3,3);
            $this->imagedata[$this->index]["user_input_flag"] = $this->get_imagedata_bit("ext",3,6,1);
            $this->imagedata[$this->index]["transparent_color_flag"] = $this->get_imagedata_bit("ext",3,7,1);
            $this->imagedata[$this->index]["delay_time"] = $this->dualbyteval($this->get_imagedata_byte("ext",4,2));
            $this->imagedata[$this->index]["transparent_color_index"] = ord($this->get_imagedata_byte("ext",6,1));
            $this->imagedata[$this->index]["offset_left"] = $this->dualbyteval($this->get_imagedata_byte("dat",1,2));
            $this->imagedata[$this->index]["offset_top"] = $this->dualbyteval($this->get_imagedata_byte("dat",3,2));
            $this->imagedata[$this->index]["width"] = $this->dualbyteval($this->get_imagedata_byte("dat",5,2));
            $this->imagedata[$this->index]["height"] = $this->dualbyteval($this->get_imagedata_byte("dat",7,2));
            $this->imagedata[$this->index]["local_color_table_flag"] = $this->get_imagedata_bit("dat",9,0,1);
            $this->imagedata[$this->index]["interlace_flag"] = $this->get_imagedata_bit("dat",9,1,1);
            $this->imagedata[$this->index]["sort_flag"] = $this->get_imagedata_bit("dat",9,2,1);
            $this->imagedata[$this->index]["color_table_size"] = pow(2,$this->get_imagedata_bit("dat",9,5,3)+1)*3;
            $this->imagedata[$this->index]["color_table"] = substr($this->imagedata[$this->index]["imagedata"],10,$this->imagedata[$this->index]["color_table_size"]);
            $this->imagedata[$this->index]["lzw_code_size"] = ord($this->get_imagedata_byte("dat",10,1));
            if($this->decoding){
                $this->orgvars[$this->index]["transparent_color_flag"] = $this->imagedata[$this->index]["transparent_color_flag"];
                $this->orgvars[$this->index]["transparent_color_index"] = $this->imagedata[$this->index]["transparent_color_index"];
                $this->orgvars[$this->index]["delay_time"] = $this->imagedata[$this->index]["delay_time"];
                $this->orgvars[$this->index]["disposal_method"] = $this->imagedata[$this->index]["disposal_method"];
                $this->orgvars[$this->index]["offset_left"] = $this->imagedata[$this->index]["offset_left"];
                $this->orgvars[$this->index]["offset_top"] = $this->imagedata[$this->index]["offset_top"];
            }
        }
        //-------------------------------------------------------
        private function get_imagedata_byte($type,$start,$length){
            if($type=="ext")
                return substr($this->imagedata[$this->index]["graphicsextension"],$start,$length);
            elseif($type=="dat")
                return substr($this->imagedata[$this->index]["imagedata"],$start,$length);
        }
        //-------------------------------------------------------
        private function get_imagedata_bit($type,$byteindex,$bitstart,$bitlength){
            if($type=="ext")
                return $this->readbits(ord(substr($this->imagedata[$this->index]["graphicsextension"],$byteindex,1)),$bitstart,$bitlength);
            elseif($type=="dat")
                return $this->readbits(ord(substr($this->imagedata[$this->index]["imagedata"],$byteindex,1)),$bitstart,$bitlength);
        }
        //-------------------------------------------------------
        private function dualbyteval($s){
            $i = ord($s[1])*256 + ord($s[0]);
            return $i;
        }
        //------------   Helper Functions ---------------------
        private function read_data_stream($first_length){
            $this->p_forward($first_length);
            $length=$this->readbyte_int();
            if($length!=0) {
                while($length!=0){
                    $this->p_forward($length);
                    $length=$this->readbyte_int();
                }
            }
            return true;
        }
        //-------------------------------------------------------
        private function loadfile($filename){
            $this->handle = fopen($filename,"rb");
            $this->pointer = 0;
        }
        //-------------------------------------------------------
        private function closefile(){
            fclose($this->handle);
            $this->handle=0;
        }
        //-------------------------------------------------------
        private function readbyte($byte_count){
            $data = fread($this->handle,$byte_count);
            $this->pointer += $byte_count;
            return $data;
        }
        //-------------------------------------------------------
        private function readbyte_int(){
            $data = fread($this->handle,1);
            $this->pointer++;
            return ord($data);
        }
        //-------------------------------------------------------
        private function readbits($byte,$start,$length){
            $bin = str_pad(decbin($byte),8,"0",STR_PAD_LEFT);
            $data = substr($bin,$start,$length);
            return bindec($data);
        }
        //-------------------------------------------------------
        private function p_rewind($length){
            $this->pointer-=$length;
            fseek($this->handle,$this->pointer);
        }
        //-------------------------------------------------------
        private function p_forward($length){
            $this->pointer+=$length;
            fseek($this->handle,$this->pointer);
        }
        //-------------------------------------------------------
        private function datapart($start,$length){
            fseek($this->handle,$start);
            $data = fread($this->handle,$length);
            fseek($this->handle,$this->pointer);
            return $data;
        }
        //-------------------------------------------------------
        private function checkbyte($byte){
            if(fgetc($this->handle)==chr($byte)){
                fseek($this->handle,$this->pointer);
                return true;
            }else{
                fseek($this->handle,$this->pointer);
                return false;
            }
        }   
        //-------------------------------------------------------
        private function checkEOF(){
            if(fgetc($this->handle)===false){
                return true;
            }else{
                fseek($this->handle,$this->pointer);
                return false;
            }
        }   
        //-------------------------------------------------------
        /** 
        * Debug Functions.  keleyi.com
        * Parses the GIF animation into single frames.
        */
        private function debug($string){
            echo "<pre>";
            for($i=0;$i<strlen($string);$i++){
                echo str_pad(dechex(ord($string[$i])),2,"0",STR_PAD_LEFT). " ";
            }
            echo "</pre>";
        }
        //-------------------------------------------------------
        private function debuglen($var,$len){
            echo "<pre>";
            for($i=0;$i<$len;$i++){
                echo str_pad(dechex(ord($var[$i])),2,"0",STR_PAD_LEFT). " ";
            }
            echo "</pre>";
        }   
        //-------------------------------------------------------
        private function debugstream($length){
            $this->debug($this->datapart($this->pointer,$length));
        }
        //-------------------------------------------------------
        /** 
        * GD Resizer Device
        * Resizes the animation frames
        */
        private function resizeframes(){
            $k=0;
            foreach($this->parsedfiles as $img){
                $src = imagecreatefromgif($img);
                $sw = $this->imagedata[$k]["width"];
                $sh = $this->imagedata[$k]["height"];
                $nw = round($sw * $this->wr);
                $nh = round($sh * $this->hr);
                $sprite = imagecreatetruecolor($nw,$nh);    
                $trans = imagecolortransparent($sprite);
                imagealphablending($sprite, false);
                imagesavealpha($sprite, true);
                imagepalettecopy($sprite,$src);                 
                imagefill($sprite,0,0,imagecolortransparent($src));
                imagecolortransparent($sprite,imagecolortransparent($src));                     
                imagecopyresized($sprite,$src,0,0,0,0,$nw,$nh,$sw,$sh);     
                imagegif($sprite,$img);
                imagedestroy($sprite);
                imagedestroy($src);
                $k++;
            }
        }
    }
?>
PHP 相关文章推荐
用PHP实现多服务器共享SESSION数据的方法
Mar 16 PHP
php 缓存函数代码
Aug 27 PHP
PHPMailer安装方法及简单实例
Nov 25 PHP
PHP中去掉字符串首尾空格的方法
May 19 PHP
PHP网页游戏学习之Xnova(ogame)源码解读(四)
Jun 23 PHP
php中的mongodb select常用操作代码示例
Sep 06 PHP
php绘制一个矩形的方法
Jan 24 PHP
php截取字符串函数分享
Feb 02 PHP
PHP统计当前在线用户数实例讲解
Oct 21 PHP
PHP删除二维数组中相同元素及数组重复值的方法示例
May 05 PHP
PHP实现下载远程图片保存到本地的方法
Jun 19 PHP
php DES加密算法实例分析
Sep 18 PHP
PHP数据库链接类(PDO+Access)实例分享
Dec 05 #PHP
php函数指定默认值方法的小例子
Dec 04 #PHP
PHP函数microtime()用法与说明
Dec 04 #PHP
php实现memcache缓存示例讲解
Dec 04 #PHP
php实现文件下载(支持中文文名)
Dec 04 #PHP
php指定函数参数默认值示例代码
Dec 04 #PHP
根据中文裁减字符串函数的php代码
Dec 03 #PHP
You might like
php数组函数序列之array_search()- 按元素值返回键名
2011/11/04 PHP
php打开远程文件的方法和风险及解决方法
2013/11/12 PHP
基于PHP实现用户登录注册功能的详细教程
2020/08/04 PHP
window.open()弹出居中的窗口
2007/02/01 Javascript
JS 的应用开发初探(mootools)
2009/12/19 Javascript
jquery json 实例代码
2010/12/02 Javascript
如何获取JQUERY AJAX返回的JSON结果集实现代码
2012/12/10 Javascript
简体中文转换繁体中文(实现代码)
2013/12/25 Javascript
jquery文本框中的事件应用以输入邮箱为例
2014/05/06 Javascript
用Jquery.load载入页面后样式没了页面混乱的解决方法
2014/10/20 Javascript
使用jQueryMobile实现滑动翻页效果的方法
2015/02/04 Javascript
JavaScript多线程详解
2015/08/12 Javascript
js窗口关闭提示信息(兼容IE和firefox)
2015/10/23 Javascript
jQuery多条件筛选如何实现
2015/11/04 Javascript
完美解决jQuery 鼠标快速滑过后,会执行多次滑出的问题
2016/12/08 Javascript
JavaScript两个变量交换值的实现方法
2017/03/01 Javascript
AngularJs分页插件使用详解
2018/06/30 Javascript
CKEditor4配置与开发详细中文说明文档
2018/10/08 Javascript
[28:48]《真视界》- 2017年国际邀请赛
2017/09/27 DOTA
在Docker上部署Python的Flask框架的教程
2015/04/08 Python
Django发送html邮件的方法
2015/05/26 Python
Python表示矩阵的方法分析
2017/05/26 Python
python实现傅里叶级数展开的实现
2018/07/21 Python
Python实现处理逆波兰表达式示例
2018/07/30 Python
python3 unicode列表转换为中文的实例
2018/10/26 Python
python3安装crypto出错及解决方法
2019/07/30 Python
python判断变量是否为int、字符串、列表、元组、字典的方法详解
2020/02/13 Python
python3获取控制台输入的数据的具体实例
2020/08/16 Python
详解python程序中的多任务
2020/09/16 Python
6种非常炫酷的CSS3按钮边框动画特效
2016/03/16 HTML / CSS
HTML5 实战PHP之Web页面表单设计
2011/10/09 HTML / CSS
HTML5实践-图片设置成灰度图
2012/11/12 HTML / CSS
京剧自荐信
2014/01/26 职场文书
信息学院毕业生自荐信范文
2014/03/04 职场文书
租赁协议书
2015/01/27 职场文书
解决pytorch读取自制数据集出现过的问题
2021/05/31 Python