欢迎您访问程序员文章站本站旨在为大家提供分享程序员计算机编程知识!
您现在的位置是: 首页  >  IT编程

PHP基于yii框架实现生成ICO图标

程序员文章站 2023-11-22 11:42:40
1,phpthumb_ico 是生成ico图标的类,源码如下 class phpthumb_ico { function phpthumb_ico()...

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] .= "\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));
  }
 
}

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>