使用404被动生成缩略图
来源:互联网 发布:mac系统游戏 编辑:程序博客网 时间:2024/05/19 17:24
在我们的项目中,图片是根据模板的不同显示不同的规格,所以无法预先生成缩略图。而图片是存储在专门的图片文件服务器上的,我们要求图片请求除第一次生成之外,访问的是真实的图片文件。主要思路是通过404跳转生成缩略图。具体方法:
1. 图片上传到文件服务器,图片的相对路径保存到相应的数据字段中。
2.模板显示的时候,根据模板要求,生成该图片缩略图的URL,缩略图URL中包含有图片原始地址,缩略图大小,缩略规则,水印规则
/** * 根据原图名获取缩略图的访问地址,规格段需要进行加密 * * @param String $filename 文件名 * @param int $width 宽度 * @param int $height 高度 * @param Char $tyep f:fix,fw:fix width,fh:fix height,c:cut,a:auto,n:原图,不做任何处理,图片生成方式 * @param $watermark 水印规则,0表示不加水印 * @param String $toJpeg 是否转换为jpg y:转换 n:不转换 * @return String 缩略图访问地址 */public static function getImgUrl($filename,$width=0,$height=0,$type='f',$watermark=0,$toJpeg='n'){//如果是远程路径,直接返回if(strpos($filename,"http://") === 0){return $filename;}$base_img_url = IMG_BASE_URL;if($filename == ""){return DEFAULT_IMG_URL;}if($type == 'n'){return $base_img_url.$filename;}$extend = pathinfo($filename);$ext = strtolower($extend["extension"]);//是否转换为jpgif(($ext == 'png') && ($toJpeg == 'y')){$format = 'jpg';}else{$format = $ext;}//$url = str_replace("images",$base_img_url,$filename);$url = $base_img_url.$filename;$width = intval($width);$height = intval($height);if($watermark===0){return str_replace(".$ext",'_'.$ext.'_cacheimages'.'_H_'.Util::encrypt_unrand($width.'_'.$height."_$type").".".$format,$url);}else{return str_replace(".$ext",'_'.$ext.'_cacheimages'.'_H_'.Util::encrypt_unrand($width.'_'.$height."_$type"."_".$watermark).".".$format,$url);}}
3.浏览器向图片服务器请求缩略图的URL,该URL 对应的图片如果已经生成则正常访问
4.如果该图片不存在,则触发404跳转,跳转到我们设定的缩略图生成文件。这一步需要在web服务中设置,将默认的404文件 改成我们的缩略图生成文件,我的是Apache,
<VirtualHost *>serverName img.xxx.comHeader set Access-Control-Allow-Origin http://www.xxx.comDocumentRoot D:/www/xxx/trunk/static/<Directory "D:/www/xxx/trunk/static/"> Options Indexes FollowSymLinks MultiViews AllowOverride All Order allow,deny Allow from all</Directory><span style="background-color: rgb(255, 255, 153);">ErrorDocument 404 /imageServer/404.php</span></VirtualHost>
5.缩略图生成文件时,先解析URL,得出缩略图的原图和各种规则,然后生成,并保存到URL所指定的地址,然后直接输出缩略图数据,显示在浏览器中。
/** * 404错误页面处理图片缩略图生成 */include "config.php";$imgpath = $_SERVER['REDIRECT_URL'] ? $_SERVER['REDIRECT_URL'] : $_SERVER['REQUEST_URI'];$imgpath = substr($imgpath,1,strlen($imgpath)-1);$pos = strpos($imgpath,'?');if($pos !== false){$imgpath = substr($imgpath,0,$pos);}$imgarr = pathinfo($imgpath);if(!in_array(trim(strtolower($imgarr['extension'])),array('jpg','jpeg','gif','png','bmp'))){exit;}$filename = $imgarr['filename'];$arr = explode("_",$filename);$arr_len = count($arr);/** 加密后,解密 **/$spec = explode("_",decrypt2($arr[$arr_len-1]));$w = $spec[0];$h = $spec[1];if($arr[$arr_len-2] != 'H'){$w = ceil($w/2);$h = ceil($h/2);}$spec['2'] = trim($spec['2']);$type = in_array($spec['2'],array('a','f','fw','fh','c','tc','cc')) ? $spec['2'] : 'a';$watermark = isset($spec['3']) ? $spec['3'] : 0;include "imageResize.func.php";//获取原图路径$arr1 = explode("_cacheimages_",$filename);$src_name = $arr1[0];if($arr_len == 6){$file = IMG_DIR.$imgarr['dirname'].'/'.$arr[0].'_'.$arr[1].'.'.$arr[$arr_len-4];}else{$arr2 = explode("_",$src_name);$arr2_len = count($arr2);if($arr2_len == 1){$file = IMG_DIR.$imgarr['dirname'].'/'.$arr2[0].".".$imgarr['extension'];}else{$ex = strtolower ($arr2[$arr2_len-1]);if($ex == 'png' || $ex == 'jpg' || $ex == 'gif' || $ex == 'bmp'){$file = IMG_DIR.$imgarr['dirname'].'/'.$arr2[0].".".$ex;}else{$file = IMG_DIR.$imgarr['dirname'].'/'.$arr2[0].'_'.$arr2[1].".".$imgarr['extension'];}}}//获取缩略图文件名//$imgpath = str_replace('.'.$imgarr['extension'],'.'.$arr[$arr_len-3],$imgpath);$newfile = IMG_DIR.$imgpath;if(imageResize($file,$newfile,$w,$h,$type)){ob_clean();<span style="color:#ffffff;"></span><span style="background-color: rgb(255, 255, 153);">header("HTTP/1.1 200 OK");</span><span style="color:#ffffff;"></span>header("Expires: ".gmdate("D, d M Y H:i:s", time()+315360000)." GMT");header("Cache-Control: max-age=315360000");header("Content-type: image/jpeg");if($watermark==1){imageWaterMark($newfile,9,'../images/watermark150.png');}elseif($watermark==2){imageWaterMark($newfile,9,'../images/watermark200.png');}elseif($watermark==3){imageWaterMark($newfile,9,'../images/watermark250.png');}echo file_get_contents($newfile);}else{ob_clean();<span style="background-color: rgb(255, 255, 153);">header("HTTP/1.1 200 OK");</span>header("Expires: ".gmdate("D, d M Y H:i:s", time()+315360000)." GMT");header("Cache-Control: max-age=315360000");header("Content-type: image/jpeg");$newfile = IMG_DIR."images/default.png";echo file_get_contents($newfile);}function realImage($url,$key = "imgkey"){ //本地要去除项目目录(autowebsite3g_svn) $url = parse_url($url,PHP_URL_PATH); if (substr($url, 0, 14) != "/_cache_images") { return false; } else { $url = substr($url, 15); } $h = substr($url,0,2); $url = substr($url,2); $extend = pathinfo($url); if($h=='H0'){ $real_url = Util::decrypt($extend['filename'],$key); $real_url_info = pathinfo($real_url); $file_info = explode('_', $real_url_info['filename']); $widthandheight_info = explode('x', $file_info[count($file_info)-2]); $new_widthandheight = strval(intval($widthandheight_info[0])/2)."x".strval(intval($widthandheight_info[1])/2); return str_replace($file_info[count($file_info)-2],$new_widthandheight,$real_url); }else{ return decrypt($extend['filename'],$key); }} function decrypt2($txt, $key = 'anihc ctI') { if($key == 'ewebsoft'){ return $txt; } $txt = str_replace("@","_",$txt); $chars = "ABCDEFGHIJKLMNOPQRSTUVWXYZabcdefghijklmnopqrstuvwxyz0123456789-_."; $ikey = "-x6g6ZWm2G9g_vr0Bo.pOq3kRIxsZ6rm"; $knum = 0; $i = 0; $tlen = strlen($txt); while (isset($key{$i})) $knum +=ord($key{$i++}); $ch1 = $txt{$knum % $tlen}; $nh1 = strpos($chars, $ch1); $txt = substr_replace($txt, '', $knum % $tlen--, 1); if(strlen($txt)==0){ //TODO错误处理 echo '非法参数';exit; } $ch2 = $txt{$nh1 % $tlen}; $nh2 = strpos($chars, $ch2); $txt = substr_replace($txt, '', $nh1 % $tlen--, 1); if(strlen($txt)==0){ //TODO错误处理 echo '非法参数';exit; } $ch3 = $txt{$nh2 % $tlen}; $nh3 = strpos($chars, $ch3); $txt = substr_replace($txt, '', $nh2 % $tlen--, 1); $nhnum = $nh1 + $nh2 + $nh3; $mdKey = substr(md5(md5(md5($key . $ch1) . $ch2 . $ikey) . $ch3), $nhnum % 8, $knum % 8 + 16); $tmp = ''; $j = 0; $k = 0; $tlen = strlen($txt); $klen = strlen($mdKey); for ($i = 0; $i < $tlen; $i++) { $k = $k == $klen ? 0 : $k; $j = strpos($chars, $txt{$i}) - $nhnum - ord($mdKey{$k++}); while ($j < 0) $j+=64; $tmp .= $chars{$j}; } $tmp = str_replace(array('-', '#', '.','@'),array('+', '/', '=','_'), $tmp); return base64_decode($tmp); } /** 功能:PHP图片水印 (水印支持图片或文字)* 参数:*$groundImage 背景图片,即需要加水印的图片,暂只支持GIF,JPG,PNG格式;*$waterPos水印位置,有10种状态,0为随机位置;*1为顶端居左,2为顶端居中,3为顶端居右;*4为中部居左,5为中部居中,6为中部居右;*7为底端居左,8为底端居中,9为底端居右;*$waterImage图片水印,即作为水印的图片,暂只支持GIF,JPG,PNG格式;*$waterText文字水印,即把文字作为为水印,支持ASCII码,不支持中文;*$textFont文字大小,值为1、2、3、4或5,默认为5;*$textColor文字颜色,值为十六进制颜色值,默认为#FF0000(红色);** 注意:Support GD 2.0,Support FreeType、GIF Read、GIF Create、JPG 、PNG*$waterImage 和 $waterText 最好不要同时使用,选其中之一即可,优先使用 $waterImage。*当$waterImage有效时,参数$waterString、$stringFont、$stringColor均不生效。*加水印后的图片的文件名和 $groundImage 一样。* 作者:longware @ 2004-11-3 14:15:13*/function imageWaterMark($groundImage,$waterPos=0,$waterImage="",$waterText="",$textFont=5,$textColor="#FF0000"){ $isWaterImage = FALSE; $formatMsg = "暂不支持该文件格式,请用图片处理软件将图片转换为GIF、JPG、PNG格式。"; //读取水印文件 if(!empty($waterImage) && file_exists($waterImage)){ $isWaterImage = TRUE; $water_info = getimagesize($waterImage); $water_w = $water_info[0];//取得水印图片的宽 $water_h = $water_info[1];//取得水印图片的高 switch($water_info[2]){//取得水印图片的格式 case 1:$water_im = imagecreatefromgif($waterImage);break; case 2:$water_im = imagecreatefromjpeg($waterImage);break; case 3:$water_im = imagecreatefrompng($waterImage);break; default:die($formatMsg); } } //读取背景图片 if(!empty($groundImage) && file_exists($groundImage)){ $ground_info = getimagesize($groundImage); $ground_w = $ground_info[0];//取得背景图片的宽 $ground_h = $ground_info[1];//取得背景图片的高 switch($ground_info[2])//取得背景图片的格式 { case 1:$ground_im = imagecreatefromgif($groundImage);break; case 2:$ground_im = imagecreatefromjpeg($groundImage);break; case 3:$ground_im = imagecreatefrompng($groundImage);break; default:die($formatMsg); } }else{ die("需要加水印的图片不存在!"); } //水印位置 if($isWaterImage)//图片水印 { $w = $water_w; $h = $water_h; $label = "图片的"; }else{//文字水印 $temp = imagettfbbox(ceil($textFont*5),0,"./cour.ttf",$waterText);//取得使用 TrueType 字体的文本的范围 $w = $temp[2] - $temp[6]; $h = $temp[3] - $temp[7]; unset($temp); $label = "文字区域"; } if( ($ground_w<$w) || ($ground_h<$h) ){ echo "需要加水印的图片的长度或宽度比水印".$label."还小,无法生成水印!"; return; } switch($waterPos){ case 0://随机 $posX = rand(0,($ground_w - $w)); $posY = rand(0,($ground_h - $h)); break; case 1://1为顶端居左 $posX = 0; $posY = 0; break; case 2://2为顶端居中 $posX = ($ground_w - $w) / 2; $posY = 0; break; case 3://3为顶端居右 $posX = $ground_w - $w; $posY = 0; break; case 4://4为中部居左 $posX = 0; $posY = ($ground_h - $h) / 2; break; case 5://5为中部居中 $posX = ($ground_w - $w) / 2; $posY = ($ground_h - $h) / 2; break; case 6://6为中部居右 $posX = $ground_w - $w; $posY = ($ground_h - $h) / 2; break; case 7://7为底端居左 $posX = 0; $posY = $ground_h - $h; break; case 8://8为底端居中 $posX = ($ground_w - $w) / 2; $posY = $ground_h - $h; break; case 9://9为底端居右 $posX = $ground_w - $w - 10; // -10 是距离右侧10px 可以自己调节 $posY = $ground_h - $h - 0; // -10 是距离底部10px 可以自己调节 break; default://随机 $posX = rand(0,($ground_w - $w)); $posY = rand(0,($ground_h - $h)); break; } //设定图像的混色模式 imagealphablending($ground_im, true); if($isWaterImage){//图片水印 imagecopy($ground_im, $water_im, $posX, $posY, 0, 0, $water_w,$water_h);//拷贝水印到目标文件 }else{//文字水印 if( !emptyempty($textColor) && (strlen($textColor)==7) ){ $R = hexdec(substr($textColor,1,2)); $G = hexdec(substr($textColor,3,2)); $B = hexdec(substr($textColor,5)); }else{ die("水印文字颜色格式不正确!"); } imagestring ( $ground_im, $textFont, $posX, $posY, $waterText, imagecolorallocate($ground_im, $R, $G, $B)); } //生成水印后的图片 @unlink($groundImage); switch($ground_info[2]){//取得背景图片的格式 case 1:imagegif($ground_im,$groundImage);break; case 2:imagejpeg($ground_im,$groundImage);break; case 3:imagepng($ground_im,$groundImage);break; default:die($errorMsg); } //释放内存 if(isset($water_info)) unset($water_info); if(isset($water_im)) imagedestroy($water_im); unset($ground_info); imagedestroy($ground_im);}注意上面高亮的部分,这是将返回状态从404改回到200。否则在第一次生成的时候,浏览器发现状态是404就不显示图片了。
0 0
- 使用404被动生成缩略图
- 使用AVFoundation生成缩略图
- 使用七牛云存储生成缩略图
- 扩展--使用AVFoundation生成缩略图
- nginx使用image_filter生成缩略图 -- fasdfs海量图片缩略图整合
- java使用JMagick生成高质量缩略图
- Silverlight缩略图生成(使用WriteableBitmap类)
- php生成缩略图(使用gd库)
- php使用GD生成图片的缩略图
- 使用epeg生成无压缩的缩略图
- 关于使用thumbnailator生成缩略图异常问题
- 使用PHP GD库生成缩略图
- 使用PIL生成用户头像缩略图
- laravel 使用Intervention/image生成缩略图
- 生成缩略图
- 生成缩略图
- 生成缩略图
- 生成缩略图
- Codeforces 487B. Strip DP+线段树+二分
- 解决方案——Connect to an old database using LocalDB in VS
- ejabberd安装步骤+Mysql配置
- MySQL死锁问题实例分析及解决方法
- [LeetCode刷题记录]190-191 Number of 1 Bits & Reverse Bits
- 使用404被动生成缩略图
- CloudFlare resources and downloads
- 内存映射文件
- VC中句柄、指针、ID之间的转换
- 网络工程师枕边书:精选30本图书抢先读
- 【PLSQL】触发器trigger类型,状态,参数
- leetcode Merge k Sorted Lists
- mapreduce中map数量计算
- 实用 .htaccess 用法大全