PHP基于yii框架实现生成ICO图标
1,phpthumb_ico是生成ICO图标的类,源码如下
classphpthumb_ico{ functionphpthumb_ico(){ returntrue; } functionGD2ICOstring(&$gd_image_array){ foreach($gd_image_arrayas$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'; } } //maskbitsare32-bitalignedperscanline 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_arrayas$key=>$gd_image){ $biSizeImage=$ImageWidths[$key]*$ImageHeights[$key]*($bpp[$key]/8); //BITMAPINFOHEADER-40bytes $BitmapInfoHeader[$key]=''; $BitmapInfoHeader[$key].="\x28\x00\x00\x00";//DWORDbiSize; $BitmapInfoHeader[$key].=$this->LittleEndian2String($ImageWidths[$key],4);//LONGbiWidth; //ThebiHeightmemberspecifiesthecombined //heightoftheXORandANDmasks. $BitmapInfoHeader[$key].=$this->LittleEndian2String($ImageHeights[$key]*2,4);//LONGbiHeight; $BitmapInfoHeader[$key].="\x01\x00";//WORDbiPlanes; $BitmapInfoHeader[$key].=chr($bpp[$key])."\x00";//wBitCount; $BitmapInfoHeader[$key].="\x00\x00\x00\x00";//DWORDbiCompression; $BitmapInfoHeader[$key].=$this->LittleEndian2String($biSizeImage,4);//DWORDbiSizeImage; $BitmapInfoHeader[$key].="\x00\x00\x00\x00";//LONGbiXPelsPerMeter; $BitmapInfoHeader[$key].="\x00\x00\x00\x00";//LONGbiYPelsPerMeter; $BitmapInfoHeader[$key].="\x00\x00\x00\x00";//DWORDbiClrUsed; $BitmapInfoHeader[$key].="\x00\x00\x00\x00";//DWORDbiClrImportant; } $icondata="\x00\x00";//idReserved;//Reserved(mustbe0) $icondata.="\x01\x00";//idType;//ResourceType(1foricons) $icondata.=$this->LittleEndian2String(count($gd_image_array),2);//idCount;//Howmanyimages? $dwImageOffset=6+(count($gd_image_array)*16); foreach($gd_image_arrayas$key=>$gd_image){ //ICONDIRENTRYidEntries[1];//Anentryforeachimage(idCountof'em) $icondata.=chr($ImageWidths[$key]);//bWidth;//Width,inpixels,oftheimage $icondata.=chr($ImageHeights[$key]);//bHeight;//Height,inpixels,oftheimage $icondata.=chr($totalcolors[$key]);//bColorCount;//Numberofcolorsinimage(0if>=8bpp) $icondata.="\x00";//bReserved;//Reserved(mustbe0) $icondata.="\x01\x00";//wPlanes;//ColorPlanes $icondata.=chr($bpp[$key])."\x00";//wBitCount;//Bitsperpixel $dwBytesInRes=40+strlen($icXOR[$key])+strlen($icAND[$key]); $icondata.=$this->LittleEndian2String($dwBytesInRes,4);//dwBytesInRes;//Howmanybytesinthisresource? $icondata.=$this->LittleEndian2String($dwImageOffset,4);//dwImageOffset;//Whereinthefileisthisimage? $dwImageOffset+=strlen($BitmapInfoHeader[$key]); $dwImageOffset+=strlen($icXOR[$key]); $dwImageOffset+=strlen($icAND[$key]); } foreach($gd_image_arrayas$key=>$gd_image){ $icondata.=$BitmapInfoHeader[$key]; $icondata.=$icXOR[$key]; $icondata.=$icAND[$key]; } return$icondata; } functionLittleEndian2String($number,$minbytes=1){ $intstring=''; while($number>0){ $intstring=$intstring.chr($number&255); $number>>=8; } returnstr_pad($intstring,$minbytes,"\x00",STR_PAD_RIGHT); } functionGetPixelColor(&$img,$x,$y){ if(!is_resource($img)){ returnfalse; } 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图标 *@authorflashalliance */ publicfunctionactionIco(){ $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']){ case1; $resize_im=@imagecreatetruecolor(16,16); $size=16; break; case2; $resize_im=@imagecreatetruecolor(32,32); $size=32; break; case3; $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=newphpthumb_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,前台
<divclass="col-md-12"> <divclass="form-horizontalpanelpanel-defaultmargin-t-10b-img"> <divclass="panel-heading"> <divclass="pull-left"><spanclass="g-bgglyphiconglyphicon-wrenchmargin-r-2"aria-hidden="true"></span>在线制作ICO图标</div> <divclass="clearfix"></div> </div> <?php $form=$this->beginWidget('CActiveForm',array( 'id'=>'ico-form', 'htmlOptions'=>array( 'id'=>'view_table', 'class'=>'add-formpadding-10', 'enctype'=>'multipart/form-data' ), 'action'=>'/tool/ico?action=make', 'enableAjaxValidation'=>false )); ?> <divclass="form-group"> <labelclass="col-lg-2control-label">上传文件</label> <divclass="col-md-5"> <divclass="col-md-6"> <inputid="upimage"type="file"name="upimage"class="hidden"> <inputid="tmp_file"class="form-control"type="text"> </div> <divclass="col-md-6"><aclass="btnbtn-default"onclick="$('input[id=upimage]').click();">选择文件</a></div> </div> </div> <divclass="form-group"> <labelclass="col-lg-2text-right">选择尺寸</label> <divclass="col-lg-5btn-group"data-toggle="buttons"> <labelclass="btnbtn-smbtn-default"> <inputtype="radio"name="size"id="s1"value="1"checked="checked">16*16 </label> <labelclass="btnbtn-smbtn-default"> <inputtype="radio"name="size"id="s2"value="2">32*32 </label> <labelclass="btnbtn-smbtn-default"> <inputtype="radio"name="size"id="s3"value="3">48*48 </label> </div> </div> <divclass="form-group"> <labelclass="col-lg-2text-right">支持格式</label> <divclass="col-lg-5"> png,jpg,gif </div> </div> <divclass="list_back"> <inputtype="submit"value="生成"class="btnbtn-success"> </div> </div> <?php$this->endWidget();?> <?phpif(!empty($errors)or!empty($output)):?> <divclass="form-horizontalpanelpanel-defaultmargin-t-10b-img"> <divclass="panel-headingmargin-b-10"> <divclass="pull-left"><spanclass="g-bgglyphiconglyphicon-wrenchmargin-r-2"aria-hidden="true"></span>生成结果</div> <divclass="clearfix"></div> </div> <?phpif(!empty($errors)):?> <divclass="form-group"> <labelclass="col-lg-2text-right">生成失败</label> <divclass="col-lg-5"> <?phpforeach($errorsas$e):?> <?phpecho$e;?><br> <?phpendforeach;?> </div> </div> <?phpendif;?> <?PHPif(!empty($output)):?> <?php $form=$this->beginWidget('CActiveForm',array( 'id'=>'ico-form', 'htmlOptions'=>array( 'id'=>'view_table', 'class'=>'add-formpadding-10', ), 'action'=>'/tool/icoDownload', 'enableAjaxValidation'=>false )); ?> <?phpechoCHtml::hiddenField('filePath',$output);?> <divclass="form-group"> <labelclass="col-lg-2text-right">成功生成</label> <divclass="col-lg-5"> <imgalt="在线制作ICO图标_favicon.ico"src="<?phpecho$output;?>"class="margin-r-10"> <inputtype="submit"value="立即下载"class="btnbtn-smbtn-successmargin-l-10"> </div> </div> <?php$this->endWidget();?> <?phpendif;?> </div> <?phpendif;?> </div> <!--form-->
再给大家分享一个独立的类
phpthumb.ico.php
<?php ////////////////////////////////////////////////////////////// ///phpThumb()byJamesHeinrich<info@silisoftware.com>// //availableathttp://phpthumb.sourceforge.net/// ////////////////////////////////////////////////////////////// ///// //phpthumb.ico.php-.ICOoutputformatfunctions// ///// ////////////////////////////////////////////////////////////// classphpthumb_ico{ functionphpthumb_ico(){ returntrue; } functionGD2ICOstring(&$gd_image_array){ foreach($gd_image_arrayas$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'; } } //maskbitsare32-bitalignedperscanline 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_arrayas$key=>$gd_image){ $biSizeImage=$ImageWidths[$key]*$ImageHeights[$key]*($bpp[$key]/8); //BITMAPINFOHEADER-40bytes $BitmapInfoHeader[$key]=''; $BitmapInfoHeader[$key].="/x28/x00/x00/x00";//DWORDbiSize; $BitmapInfoHeader[$key].=$this->LittleEndian2String($ImageWidths[$key],4);//LONGbiWidth; //ThebiHeightmemberspecifiesthecombined //heightoftheXORandANDmasks. $BitmapInfoHeader[$key].=$this->LittleEndian2String($ImageHeights[$key]*2,4);//LONGbiHeight; $BitmapInfoHeader[$key].="/x01/x00";//WORDbiPlanes; $BitmapInfoHeader[$key].=chr($bpp[$key])."/x00";//wBitCount; $BitmapInfoHeader[$key].="/x00/x00/x00/x00";//DWORDbiCompression; $BitmapInfoHeader[$key].=$this->LittleEndian2String($biSizeImage,4);//DWORDbiSizeImage; $BitmapInfoHeader[$key].="/x00/x00/x00/x00";//LONGbiXPelsPerMeter; $BitmapInfoHeader[$key].="/x00/x00/x00/x00";//LONGbiYPelsPerMeter; $BitmapInfoHeader[$key].="/x00/x00/x00/x00";//DWORDbiClrUsed; $BitmapInfoHeader[$key].="/x00/x00/x00/x00";//DWORDbiClrImportant; } $icondata="/x00/x00";//idReserved;//Reserved(mustbe0) $icondata.="/x01/x00";//idType;//ResourceType(1foricons) $icondata.=$this->LittleEndian2String(count($gd_image_array),2);//idCount;//Howmanyimages? $dwImageOffset=6+(count($gd_image_array)*16); foreach($gd_image_arrayas$key=>$gd_image){ //ICONDIRENTRYidEntries[1];//Anentryforeachimage(idCountof'em) $icondata.=chr($ImageWidths[$key]);//bWidth;//Width,inpixels,oftheimage $icondata.=chr($ImageHeights[$key]);//bHeight;//Height,inpixels,oftheimage $icondata.=chr($totalcolors[$key]);//bColorCount;//Numberofcolorsinimage(0if>=8bpp) $icondata.="/x00";//bReserved;//Reserved(mustbe0) $icondata.="/x01/x00";//wPlanes;//ColorPlanes $icondata.=chr($bpp[$key])."/x00";//wBitCount;//Bitsperpixel $dwBytesInRes=40+strlen($icXOR[$key])+strlen($icAND[$key]); $icondata.=$this->LittleEndian2String($dwBytesInRes,4);//dwBytesInRes;//Howmanybytesinthisresource? $icondata.=$this->LittleEndian2String($dwImageOffset,4);//dwImageOffset;//Whereinthefileisthisimage? $dwImageOffset+=strlen($BitmapInfoHeader[$key]); $dwImageOffset+=strlen($icXOR[$key]); $dwImageOffset+=strlen($icAND[$key]); } foreach($gd_image_arrayas$key=>$gd_image){ $icondata.=$BitmapInfoHeader[$key]; $icondata.=$icXOR[$key]; $icondata.=$icAND[$key]; } return$icondata; } functionLittleEndian2String($number,$minbytes=1){ $intstring=''; while($number>0){ $intstring=$intstring.chr($number&255); $number>>=8; } returnstr_pad($intstring,$minbytes,"/x00",STR_PAD_RIGHT); } functionGetPixelColor(&$img,$x,$y){ if(!is_resource($img)){ returnfalse; } return@ImageColorsForIndex($img,@ImageColorAt($img,$x,$y)); } } ?>
index.php
<!DOCTYPEhtmlPUBLIC"-//W3C//DTDXHTML1.0Transitional//EN""http://www.w3.org/TR/xhtml1/DTD/xhtml1-transitional.dtd"> <htmlxmlns="http://www.w3.org/1999/xhtml"> <head> <title>ico图标</title> <metahttp-equiv="Content-Type"content="text/html;charset=utf-8"/> </head> <body> <divclass="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']){ case1; $resize_im=@imagecreatetruecolor(16,16); $size=16; break; case2; $resize_im=@imagecreatetruecolor(32,32); $size=32; break; case3; $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=newphpthumb_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><ahref="/"mce_href="/""".$filename."/"target=/"_blank/">点击下载</a>"; } }else{ echo"生成错误请重试!"; } } } ?> <formaction="index.php?action=make"method="post"enctype='multipart/form-data'> <tablewidth="90%"align="center"> <tr> <tdheight="40"><h3>请上传你要转换成.<ahref="http://ico.sevem.cn"mce_href="http://ico.sevem.cn"target="_blank">ico</a>的图片</h3> 支持格式png、jpg、gif在线转换成.<ahref="http://ico.sevem.cn"mce_href="http://ico.sevem.cn"target="_blank">ico</a>图标。如何你想制作更丰富的.<ahref="http://ico.sevem.cn"mce_href="http://ico.sevem.cn"target="_blank">ico</a>图标请<ahref="#ico"mce_href="#ico">下载ICO制作软件</a></td> </tr> <tr> <tdheight="40"><inputtype="file"name="upimage"size="30">目标尺寸: <inputtype="radio"name="size"value="1"id="s1"><labelfor="s1">16*16</label> <inputtype="radio"name="size"value="2"id="s2"checked><labelfor="s2">32*32</label> <inputtype="radio"name="size"value="3"id="s3"><labelfor="s3">48*48</label> </td> </tr> <tr> <tdheight="40"align="center"><inputtype="submit"style="width:150px;height:30px;"value="在线生成favicon.ico图标"></td> </tr> <?PHP if($output){ echo"<tr><td><divstyle="/"mce_style="/""border:1pxsolid#D8D8B2;background-color:#FFFFDD;padding:10px/">".$output."</div></td></tr>"; } ?> </table> <divstyle="display:none"mce_style="display:none"> <?php $doc=newDOMDocument(); $doc->load('http://link.qim.net.cn/xml.xml'); $links=$doc->getElementsByTagName("link"); foreach($linksas$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"<ahref="$homepage"mce_href="$homepage"title='$content'target='_blank'></a>$title</a><br>"; } ?> </div> </form> </body> </html>