PHP基于yii框架实现生成ICO图标
author:一佰互联 2019-04-27   click:163

1,phpthumb_ico 是生成ICO图标的类,源码如下

class phpthumb_ico {   function phpthumb_ico() {    return true;  }    function GD2ICOstring(&$gd_image_array) {    foreach ($gd_image_array as $key => $gd_image) {       $ImageWidths[$key] = ImageSX($gd_image);      $ImageHeights[$key] = ImageSY($gd_image);      $bpp[$key]     = ImageIsTrueColor($gd_image) ? 32 : 24;      $totalcolors[$key] = ImageColorsTotal($gd_image);       $icXOR[$key] = "";      for ($y = $ImageHeights[$key] - 1; $y >= 0; $y--) {        for ($x = 0; $x < $ImageWidths[$key]; $x++) {          $argb = $this->GetPixelColor($gd_image, $x, $y);          $a = round(255 * ((127 - $argb["alpha"]) / 127));          $r = $argb["red"];          $g = $argb["green"];          $b = $argb["blue"];           if ($bpp[$key] == 32) {            $icXOR[$key] .= chr($b).chr($g).chr($r).chr($a);          } elseif ($bpp[$key] == 24) {            $icXOR[$key] .= chr($b).chr($g).chr($r);          }           if ($a < 128) {            @$icANDmask[$key][$y] .= "1";          } else {            @$icANDmask[$key][$y] .= "0";          }        }        // mask bits are 32-bit aligned per scanline        while (strlen($icANDmask[$key][$y]) % 32) {          $icANDmask[$key][$y] .= "0";        }      }      $icAND[$key] = "";      foreach ($icANDmask[$key] as $y => $scanlinemaskbits) {        for ($i = 0; $i < strlen($scanlinemaskbits); $i += 8) {          $icAND[$key] .= chr(bindec(str_pad(substr($scanlinemaskbits, $i, 8), 8, "0", STR_PAD_LEFT)));        }      }     }     foreach ($gd_image_array as $key => $gd_image) {      $biSizeImage = $ImageWidths[$key] * $ImageHeights[$key] * ($bpp[$key] / 8);       // BITMAPINFOHEADER - 40 bytes      $BitmapInfoHeader[$key] = "";      $BitmapInfoHeader[$key] .= "x28x00x00x00";               // DWORD biSize;      $BitmapInfoHeader[$key] .= $this->LittleEndian2String($ImageWidths[$key], 4);   // LONG  biWidth;      // The biHeight member specifies the combined      // height of the XOR and AND masks.      $BitmapInfoHeader[$key] .= $this->LittleEndian2String($ImageHeights[$key] * 2, 4); // LONG  biHeight;      $BitmapInfoHeader[$key] .= "x01x00";                   // WORD  biPlanes;        $BitmapInfoHeader[$key] .= chr($bpp[$key])."x00";             // wBitCount;      $BitmapInfoHeader[$key] .= "x00x00x00x00";               // DWORD biCompression;      $BitmapInfoHeader[$key] .= $this->LittleEndian2String($biSizeImage, 4);      // DWORD biSizeImage;      $BitmapInfoHeader[$key] .= "x00x00x00x00";               // LONG  biXPelsPerMeter;      $BitmapInfoHeader[$key] .= "x00x00x00x00";               // LONG  biYPelsPerMeter;      $BitmapInfoHeader[$key] .= "x00x00x00x00";               // DWORD biClrUsed;      $BitmapInfoHeader[$key] .= "x00x00x00x00";               // DWORD biClrImportant;    }      $icondata = "x00x00";                   // idReserved;  // Reserved (must be 0)    $icondata .= "x01x00";                   // idType;    // Resource Type (1 for icons)    $icondata .= $this->LittleEndian2String(count($gd_image_array), 2); // idCount;   // How many images?     $dwImageOffset = 6 + (count($gd_image_array) * 16);    foreach ($gd_image_array as $key => $gd_image) {      // ICONDIRENTRY  idEntries[1]; // An entry for each image (idCount of "em)       $icondata .= chr($ImageWidths[$key]);           // bWidth;     // Width, in pixels, of the image      $icondata .= chr($ImageHeights[$key]);          // bHeight;     // Height, in pixels, of the image      $icondata .= chr($totalcolors[$key]);           // bColorCount;   // Number of colors in image (0 if >=8bpp)      $icondata .= "x00";                   // bReserved;    // Reserved ( must be 0)       $icondata .= "x01x00";                 // wPlanes;     // Color Planes      $icondata .= chr($bpp[$key])."x00";           // wBitCount;    // Bits per pixel       $dwBytesInRes = 40 + strlen($icXOR[$key]) + strlen($icAND[$key]);      $icondata .= $this->LittleEndian2String($dwBytesInRes, 4);    // dwBytesInRes;  // How many bytes in this resource?       $icondata .= $this->LittleEndian2String($dwImageOffset, 4);   // dwImageOffset;  // Where in the file is this image?      $dwImageOffset += strlen($BitmapInfoHeader[$key]);      $dwImageOffset += strlen($icXOR[$key]);      $dwImageOffset += strlen($icAND[$key]);    }     foreach ($gd_image_array as $key => $gd_image) {      $icondata .= $BitmapInfoHeader[$key];      $icondata .= $icXOR[$key];      $icondata .= $icAND[$key];    }     return $icondata;  }   function LittleEndian2String($number, $minbytes=1) {    $intstring = "";    while ($number > 0) {      $intstring = $intstring.chr($number & 255);      $number >>= 8;    }    return str_pad($intstring, $minbytes, "x00", STR_PAD_RIGHT);  }   function GetPixelColor(&$img, $x, $y) {    if (!is_resource($img)) {      return false;    }    return @ImageColorsForIndex($img, @ImageColorAt($img, $x, $y));  } }

2,后台

引入类:

Yii::$enableIncludePath = false;Yii::import ( "application.extensions.ico.phpthumb_ico", 1 );

解决生成黑色背景的问题

imagealphablending($resize_im, false);//不合并颜色,直接用$im图像颜色替换,包括透明色imagesavealpha($resize_im, true);//不要丢了$resize_im图像的透明色完整方法:

/**   * icoMaker 在线生成ICO图标   * @author flashalliance   */  public function actionIco() {    $this->breadcrumbs=array_merge($this->breadcrumbs,array(        "ICO图标制作"    ));    $output = "";    $errors=array();    if(isset($_GET["action"])&&$_GET["action"] == "make"){      if(isset($_FILES["upimage"]["tmp_name"]) && $_FILES["upimage"]["tmp_name"] && is_uploaded_file($_FILES["upimage"]["tmp_name"])){        if($_FILES["upimage"]["size"]>204800){          $errors[]="你上传的文件过大,最大不能超过200K。";        }        $fileext = array("image/pjpeg","image/jpeg","image/gif","image/x-png","image/png");        if(!in_array($_FILES["upimage"]["type"],$fileext)){          $errors[]="你上传的文件格式不正确,仅支持 png, jpg, gif格式。";        }        if($im = @imagecreatefrompng($_FILES["upimage"]["tmp_name"]) or $im = @imagecreatefromgif($_FILES["upimage"]["tmp_name"]) or $im = @imagecreatefromjpeg($_FILES["upimage"]["tmp_name"])){          $imginfo = @getimagesize($_FILES["upimage"]["tmp_name"]);          if(!is_array($imginfo)){            $errors[]="图像格式错误!";          }          if(empty($errors)){            switch($_POST["size"]){              case 1;              $resize_im = @imagecreatetruecolor(16,16);              $size = 16;              break;              case 2;              $resize_im = @imagecreatetruecolor(32,32);              $size = 32;              break;              case 3;              $resize_im = @imagecreatetruecolor(48,48);              $size = 48;              break;              default;              $resize_im = @imagecreatetruecolor(32,32);              $size = 32;              break;            }             imagesavealpha($im, true);            imagealphablending($resize_im, false);//不合并颜色,直接用$im图像颜色替换,包括透明色            imagesavealpha($resize_im, true);//不要丢了$resize_im图像的透明色,解决生成黑色背景的问题            imagecopyresampled($resize_im,$im,0,0,0,0,$size,$size,$imginfo[0],$imginfo[1]);             Yii::$enableIncludePath = false;            Yii::import ( "application.extensions.ico.phpthumb_ico", 1 );            $icon = new phpthumb_ico();            $gd_image_array = array($resize_im);            $icon_data = $icon->GD2ICOstring($gd_image_array);            $bas_path=dirname ( Yii::app ()->BasePath );            $bas_new_path=$bas_path."/upload/ico/";            if(!is_dir($bas_new_path)){              mkdir($bas_new_path, 0777, true);            }            $filePath=$bas_new_path. date("Ymdhis").uniqid(). rand(1,1000) . ".ico";            if(file_put_contents($filePath, $icon_data)){              $output = str_replace($bas_path,"",$filePath);            }          }        }else{          $errors[]="生成错误请重试!";        }      }    }    $this->render ( "ico",array("output"=>$output,"errors"=>$errors));  }

3,前台

<div class="col-md-12">  <div class="form-horizontal panel panel-default margin-t-10 b-img">    <div class="panel-heading">      <div class="pull-left"><span class="g-bg glyphicon glyphicon-wrench margin-r-2" aria-hidden="true"></span>在线制作ICO图标</div>      <div class="clearfix"></div>    </div><?php$form = $this->beginWidget ( "CActiveForm", array (    "id" => "ico-form",    "htmlOptions" => array (        "id" => "view_table",        "class" => "add-form padding-10",        "enctype"=>"multipart/form-data"    ),    "action"=>"/tool/ico?action=make",    "enableAjaxValidation" => false) );?>    <div class="form-group">        <label class="col-lg-2 control-label">上传文件</label>        <div class="col-md-5">          <div class="col-md-6">            <input id="upimage" type="file" name="upimage" class="hidden">            <input id="tmp_file" class="form-control" type="text">          </div>          <div class="col-md-6"><a class="btn btn-default" onclick="$("input[id=upimage]").click();">选择文件</a></div>        </div>    </div>    <div class="form-group">        <label class="col-lg-2 text-right">选择尺寸</label>        <div class="col-lg-5 btn-group" data-toggle="buttons">            <label class="btn btn-sm btn-default">             <input type="radio" name="size" id="s1" value="1" checked="checked"> 16*16            </label>            <label class="btn btn-sm btn-default">             <input type="radio" name="size" id="s2" value="2"> 32*32            </label>            <label class="btn btn-sm btn-default">             <input type="radio" name="size" id="s3" value="3"> 48*48            </label>        </div>    </div>    <div class="form-group">      <label class="col-lg-2 text-right">支持格式</label>      <div class="col-lg-5">       png,jpg,gif      </div>    </div>    <div class="list_back">      <input type="submit" value="生 成" class="btn btn-success">    </div>  </div><?php $this->endWidget(); ?><?php if(!empty($errors) or !empty($output)):?>  <div class="form-horizontal panel panel-default margin-t-10 b-img">    <div class="panel-heading margin-b-10">      <div class="pull-left"><span class="g-bg glyphicon glyphicon-wrench margin-r-2" aria-hidden="true"></span>生成结果</div>      <div class="clearfix"></div>    </div>    <?php if(!empty($errors)):?>    <div class="form-group">      <label class="col-lg-2 text-right">生成失败</label>      <div class="col-lg-5">      <?php foreach ($errors as $e):?>      <?php echo $e;?><br>      <?php endforeach;?>      </div>    </div>    <?php endif;?>    <?PHP if (!empty($output)):?>    <?php    $form = $this->beginWidget ( "CActiveForm", array (        "id" => "ico-form",        "htmlOptions" => array (            "id" => "view_table",            "class" => "add-form padding-10",        ),        "action"=>"/tool/icoDownload",        "enableAjaxValidation" => false    ) );    ?>    <?php echo CHtml::hiddenField("filePath",$output);?>    <div class="form-group">      <label class="col-lg-2 text-right">成功生成</label>      <div class="col-lg-5">        <img alt="在线制作ICO图标_favicon.ico" src="<?php echo $output;?>" class="margin-r-10">        <input type="submit" value="立即下载" class="btn btn-sm btn-success margin-l-10">      </div>    </div>    <?php $this->endWidget(); ?>    <?php endif;?>  </div><?php endif;?></div><!-- form -->

再给大家分享一个独立的类

phpthumb.ico.php

<?php ////////////////////////////////////////////////////////////// /// phpThumb() by James Heinrich <info@silisoftware.com>  // //    available at http://phpthumb.sourceforge.net   /// ////////////////////////////////////////////////////////////// ///                             // // phpthumb.ico.php - .ICO output format functions     // //                             /// ////////////////////////////////////////////////////////////// class phpthumb_ico {   function phpthumb_ico() {     return true;   }   function GD2ICOstring(&$gd_image_array) {     foreach ($gd_image_array as $key => $gd_image) {       $ImageWidths[$key] = ImageSX($gd_image);       $ImageHeights[$key] = ImageSY($gd_image);       $bpp[$key]     = ImageIsTrueColor($gd_image) ? 32 : 24;       $totalcolors[$key] = ImageColorsTotal($gd_image);       $icXOR[$key] = "";       for ($y = $ImageHeights[$key] - 1; $y >= 0; $y--) {         for ($x = 0; $x < $ImageWidths[$key]; $x++) {           $argb = $this->GetPixelColor($gd_image, $x, $y);           $a = round(255 * ((127 - $argb["alpha"]) / 127));           $r = $argb["red"];           $g = $argb["green"];           $b = $argb["blue"];           if ($bpp[$key] == 32) {             $icXOR[$key] .= chr($b).chr($g).chr($r).chr($a);           } elseif ($bpp[$key] == 24) {             $icXOR[$key] .= chr($b).chr($g).chr($r);           }           if ($a < 128) {             @$icANDmask[$key][$y] .= "1";           } else {             @$icANDmask[$key][$y] .= "0";           }         }         // mask bits are 32-bit aligned per scanline         while (strlen($icANDmask[$key][$y]) % 32) {           $icANDmask[$key][$y] .= "0";         }       }       $icAND[$key] = "";       foreach ($icANDmask[$key] as $y => $scanlinemaskbits) {         for ($i = 0; $i < strlen($scanlinemaskbits); $i += 8) {           $icAND[$key] .= chr(bindec(str_pad(substr($scanlinemaskbits, $i, 8), 8, "0", STR_PAD_LEFT)));         }       }     }     foreach ($gd_image_array as $key => $gd_image) {       $biSizeImage = $ImageWidths[$key] * $ImageHeights[$key] * ($bpp[$key] / 8);       // BITMAPINFOHEADER - 40 bytes       $BitmapInfoHeader[$key] = "";       $BitmapInfoHeader[$key] .= "/x28/x00/x00/x00";               // DWORD biSize;       $BitmapInfoHeader[$key] .= $this->LittleEndian2String($ImageWidths[$key], 4);   // LONG  biWidth;       // The biHeight member specifies the combined       // height of the XOR and AND masks.       $BitmapInfoHeader[$key] .= $this->LittleEndian2String($ImageHeights[$key] * 2, 4); // LONG  biHeight;       $BitmapInfoHeader[$key] .= "/x01/x00";                   // WORD  biPlanes;         $BitmapInfoHeader[$key] .= chr($bpp[$key])."/x00";             // wBitCount;       $BitmapInfoHeader[$key] .= "/x00/x00/x00/x00";               // DWORD biCompression;       $BitmapInfoHeader[$key] .= $this->LittleEndian2String($biSizeImage, 4);      // DWORD biSizeImage;       $BitmapInfoHeader[$key] .= "/x00/x00/x00/x00";               // LONG  biXPelsPerMeter;       $BitmapInfoHeader[$key] .= "/x00/x00/x00/x00";               // LONG  biYPelsPerMeter;       $BitmapInfoHeader[$key] .= "/x00/x00/x00/x00";               // DWORD biClrUsed;       $BitmapInfoHeader[$key] .= "/x00/x00/x00/x00";               // DWORD biClrImportant;     }     $icondata = "/x00/x00";                   // idReserved;  // Reserved (must be 0)     $icondata .= "/x01/x00";                   // idType;    // Resource Type (1 for icons)     $icondata .= $this->LittleEndian2String(count($gd_image_array), 2); // idCount;   // How many images?     $dwImageOffset = 6 + (count($gd_image_array) * 16);     foreach ($gd_image_array as $key => $gd_image) {       // ICONDIRENTRY  idEntries[1]; // An entry for each image (idCount of "em)       $icondata .= chr($ImageWidths[$key]);           // bWidth;     // Width, in pixels, of the image       $icondata .= chr($ImageHeights[$key]);          // bHeight;     // Height, in pixels, of the image       $icondata .= chr($totalcolors[$key]);           // bColorCount;   // Number of colors in image (0 if >=8bpp)       $icondata .= "/x00";                   // bReserved;    // Reserved ( must be 0)       $icondata .= "/x01/x00";                 // wPlanes;     // Color Planes       $icondata .= chr($bpp[$key])."/x00";           // wBitCount;    // Bits per pixel       $dwBytesInRes = 40 + strlen($icXOR[$key]) + strlen($icAND[$key]);       $icondata .= $this->LittleEndian2String($dwBytesInRes, 4);    // dwBytesInRes;  // How many bytes in this resource?       $icondata .= $this->LittleEndian2String($dwImageOffset, 4);   // dwImageOffset;  // Where in the file is this image?       $dwImageOffset += strlen($BitmapInfoHeader[$key]);       $dwImageOffset += strlen($icXOR[$key]);       $dwImageOffset += strlen($icAND[$key]);     }     foreach ($gd_image_array as $key => $gd_image) {       $icondata .= $BitmapInfoHeader[$key];       $icondata .= $icXOR[$key];       $icondata .= $icAND[$key];     }     return $icondata;   }   function LittleEndian2String($number, $minbytes=1) {     $intstring = "";     while ($number > 0) {       $intstring = $intstring.chr($number & 255);       $number >>= 8;     }     return str_pad($intstring, $minbytes, "/x00", STR_PAD_RIGHT);   }   function GetPixelColor(&$img, $x, $y) {     if (!is_resource($img)) {       return false;     }     return @ImageColorsForIndex($img, @ImageColorAt($img, $x, $y));   } } ?>

 index.php

<!DOCTYPE html PUBLIC "-//W3C//DTD XHTML 1.0 Transitional//EN" "http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"><html xmlns="http://www.w3.org/1999/xhtml"><head> <title>ico图标</title><meta http-equiv="Content-Type" content="text/html; charset=utf-8" /></head> <body>  <div class="center">		<?PHP $output = ""; if(isset($_GET["action"])&&$_GET["action"] == "make"){   if(isset($_FILES["upimage"]["tmp_name"]) && $_FILES["upimage"]["tmp_name"] && is_uploaded_file($_FILES["upimage"]["tmp_name"])){     if($_FILES["upimage"]["type"]>210000){       echo "你上传的文件体积超过了限制 最大不能超过200K";       exit();     }     $fileext = array("image/pjpeg","image/gif","image/x-png","image/png","image/jpeg","image/jpg");     if(!in_array($_FILES["upimage"]["type"],$fileext)){       echo "你上传的文件格式不正确 仅支持 jpg,gif,png";       exit();     }     if($im = @imagecreatefrompng($_FILES["upimage"]["tmp_name"]) or $im = @imagecreatefromgif($_FILES["upimage"]["tmp_name"]) or $im = @imagecreatefromjpeg($_FILES["upimage"]["tmp_name"])){       $imginfo = @getimagesize($_FILES["upimage"]["tmp_name"]);       if(!is_array($imginfo)){         echo "图形格式错误!";       }       switch($_POST["size"]){         case 1;           $resize_im = @imagecreatetruecolor(16,16);           $size = 16;           break;         case 2;           $resize_im = @imagecreatetruecolor(32,32);           $size = 32;           break;         case 3;           $resize_im = @imagecreatetruecolor(48,48);           $size = 48;           break;         default;           $resize_im = @imagecreatetruecolor(32,32);           $size = 32;           break;       }       imagecopyresampled($resize_im,$im,0,0,0,0,$size,$size,$imginfo[0],$imginfo[1]);       include "phpthumb.ico.php";       $icon = new phpthumb_ico();       $gd_image_array = array($resize_im);       $icon_data = $icon->GD2ICOstring($gd_image_array);       $filename = "temp/".date("Ymdhis").rand(1,1000).".ico";       if(file_put_contents($filename, $icon_data)){         $output = "生成成功!请点右键->另存为 保存到本地<br><a href="/" mce_href="/""".$filename."/" target=/"_blank/">点击下载</a>";       }     }else{       echo "生成错误请重试!";     }   }   } ?> 		<form action="index.php?action=make" method="post" enctype="multipart/form-data"> 		<table width="90%" align="center"> 			<tr> 			 <td height="40"><h3>请上传你要转换成.<a href="http://ico.sevem.cn" mce_href="http://ico.sevem.cn" target="_blank">ico</a>的图片</h3>			 支持格式 png、jpg、gif在线转换成.<a href="http://ico.sevem.cn" mce_href="http://ico.sevem.cn" target="_blank">ico</a>图标。如何你想制作更丰富的.<a href="http://ico.sevem.cn" mce_href="http://ico.sevem.cn" target="_blank">ico</a>图标请<a href="#ico" mce_href="#ico">下载ICO制作软件</a></td> 			</tr> 			<tr> 			 <td height="40"><input type="file" name="upimage" size="30">目标尺寸: 				<input type="radio" name="size" value="1" id="s1"><label for="s1">16*16</label> 				<input type="radio" name="size" value="2" id="s2" checked><label for="s2">32*32</label> 				<input type="radio" name="size" value="3" id="s3"><label for="s3">48*48</label> 			 </td> 			</tr> 			 			<tr> 			 <td height="40" align="center"><input type="submit" style="width:150px; height:30px;" value="在线生成favicon.ico图标"></td> 			</tr> 			<?PHP 			if($output){ 				echo "<tr><td><div style="/" mce_style="/""border:1px solid #D8D8B2;background-color:#FFFFDD;padding:10px/">".$output."</div></td></tr>"; 			} 			?> 		</table> 		<div style="display:none" mce_style="display:none"><?php  $doc = new DOMDocument();  $doc->load( "http://link.qim.net.cn/xml.xml" );    $links = $doc->getElementsByTagName( "link" );  foreach( $links as $link )  {  $publishers = $link->getElementsByTagName( "homepage" );  $homepage = $publishers->item(0)->nodeValue;    $titles = $link->getElementsByTagName( "title" );  $title = $titles->item(0)->nodeValue;    $contents = $link->getElementsByTagName( "content" );  $content = $contents->item(0)->nodeValue;    echo "<a href="$homepage" mce_href="$homepage" title="$content" target="_blank" ></a>$title</a><br>";  }  ?> </div>		</form> 			</body> </html>