我在访问时光网、网易云音乐等网站时,发现将它们页面中的一些图片URL修改一下就可以得到不同尺寸的图片,于是思考了其实现方案,我的思路是:URL Rewrite + 实时处理 + 缓存,对用户请求的URL进行重写,然后利用图片处理类库对图片进行处理,接着缓存该尺寸图片并输出到浏览器。使用PHP和Node.js实现了一遍,基本达到了需要的效果。
1、Nginx+Node.js(express)实现
URL重写
这里Nginx主要是做一个URL重写和反向代理的功能,配置如下所示:
location ~ /upload/{ if ($request_uri ~* ^/upload/(.+)_(\d+)x(\d+)\.(jpg|png|gif)$) { set $src $1; set $w $2; set $h $3; set $t $4; rewrite . /resize"color: #3366ff">http://127.0.0.1/upload/147332819224704_400x300.jpg的地址时,便会被代理到http://127.0.0.1:3000/resize"color: #800000">图片实时处理
我们在Node.js中实时处理图片,进行缩放、模糊、水印等操作,之后将其缓存起来并输出到浏览器。Node.js自身API并不擅长图片的处理,我们可以借助第三方类库来实现,这里推荐GraphicsMagick或ImageMagick,使用它们之前先安装gm模块:
npm install gm --save
接着便可以使用GraphicsMagick了,该模块的API可以参考GM模块API介绍。图片处理的实现如下:app.get('/resize',function(req,res){ var src = req.query.src, width = req.query.w, height = req.query.h, type = req.query.type; var imgFile = uploadDir+src+'.'+type; var notFound = '不好意思,该图片不存在或已被删除!'; var thumb = getThumbImg(src,width,height,type); if(isFileExists(imgFile)){ if(isFileExists(thumb)){ res.type(type).sendFile(__dirname+'/'+thumb); }else{ imgResize(imgFile,thumb,width,height,type,res); } }else{ res.status(404).send(notFound); } }); function imgResize(f,th,w,h,t,r){ var imgSize = sizeOf(f); if(!w||!h||w>=imgSize.width||h>=imgSize.height){ r.type(t).sendFile(__dirname+'/'+f); }else{ imageMagick(f) .resize(w,h,'!') .stream(function(err, stdout, stderr) { if (err) { console.log(err); res.end(); } var ws = fs.createWriteStream(th); stdout.pipe(ws); r.type(t); stdout.pipe(r); }); } } function isFileExists(filePath){ var bool = !0; try{ fs.accessSync(filePath,fs.constants.F_OK); }catch(err){ bool = !1; } return bool; }如上代码所示,当用户访问http://127.0.0.1/upload/147332819224704_400x300.jpg时,如果147332819224704这张图片存在,且400x300这个尺寸也存在,则直接输出这张图片,如不存在,则生成一张该尺寸的图片保存并输出到浏览器。如果提供的尺寸超出了图片的原始尺寸,则直接输出原图。我们不仅可以修改尺寸,也可以进行模糊、打水印等操作,这里就不多介绍了。
如果不用Nginx反向代理也是可以的,使用express的正则路由实现,如下所示:
app.get(/^\/upload\/(.+)_(\d+)x(\d+)\.(jpg|png|gif)$/,function(req,res){ var src = RegExp.$1, width = RegExp.$2, height = RegExp.$3, type = RegExp.$4; var imgFile = uploadDir+src+'.'+type; var notFound = '不好意思,该图片不存在或已被删除!'; var thumb = getThumbImg(src,width,height,type); if(isFileExists(imgFile)){ if(isFileExists(thumb)){ res.type(type).sendFile(__dirname+'/'+thumb); }else{ imgResize(imgFile,thumb,width,height,type,res); } }else{ res.status(404).send(notFound); } });2、Apache+PHP实现
首先得搭建windows下php开发环境,我本人用的是apache2+php5.6,具体的搭建步骤网上一大堆,便不再累述。
开启apache rewrite功能
首先我们得开启Apache rewrite模块功能,去掉配置文件http.conf中LoadModule rewrite_module modules/mod_rewrite.so前面的注释,然后设置Directory块下AllowOverride All,可能有多处,接着重启Apache服务。
配置.htaccess文件
在DocumentRoot目录下,新建.htaccess文件,如果创建不了,可以先创建一个文本,然后另存为,在弹出的对话框文件名处填写".htaccess"即可。之后,编写URL重写规则,如下所示:
RewriteEngine on RewriteCond %{REQUEST_FILENAME} !-f RewriteRule ^upload/(.+)_([0-9]+)x([0-9]+)\.(jpg|png|gif)$ resize.php"color: #3366ff">http://127.0.0.1/upload/147332819224704_400x300.jpg地址重写为http://127.0.0.1/resize.php/src=147332819224704&w=400&h=300&type=jpg。
功能实现
接下来便是功能的实现,逻辑和nodejs版逻辑一致,代码如下:
function getThumbImg($src,$w,$h,$type) { global $thumbs; return $_SERVER['DOCUMENT_ROOT'].$thumbs.$src.'_'.$w.'_'.$h.'.'.$type; } function imgResize($f,$th,$w,$h,$t) { $imagick = new Imagick(); $imagick->readImage($_SERVER['DOCUMENT_ROOT'].'\\'.$f); $width = $imagick->getImageWidth(); $height = $imagick->getImageHeight(); if(!$w||!$h||$w>=$width||$h>=$height){ header('Content-Type:image/'.$t); echo file_get_contents($_SERVER['DOCUMENT_ROOT'].'\\'.$f); }else{ $imagick->stripImage(); $imagick->cropThumbnailImage($w, $h); $imagick->writeImage($th); header('Content-Type:image/'.$t); echo $imagick->getImageBlob(); $imagick->clear(); $imagick->destroy(); } } $uploadDir = "uploads/images/"; $thumbs = "uploads/thumbs/"; $src = $_GET['src']; $width = $_GET['w']; $height = $_GET['h']; $type = $_GET['type']; $imgFile = $uploadDir.$src.'.'.$type; $notFound = '不好意思,该图片不存在或已被删除!'; $thumb = getThumbImg($src,$width,$height,$type); if(file_exists($imgFile)){ if(file_exists($thumb)){ header('Content-Type:image/'.$type); echo file_get_contents($thumb); }else{ imgResize($imgFile,$thumb,$width,$height,$type); } }else{ header("HTTP/1.0 404 Not Found"); header("status: 404"); echo $notFound; }至此,图片访问实时处理也就完成了。其实大部分图片服务器都需要这样的功能,而不是事先生成好几套尺寸的图片。
以上就是本文的全部内容,希望对大家的学习有所帮助,也希望大家多多支持。
免责声明:本站资源来自互联网收集,仅供用于学习和交流,请遵循相关法律法规,本站一切资源不代表本站立场,如有侵权、后门、不妥请联系本站删除!
P70系列延期,华为新旗舰将在下月发布
3月20日消息,近期博主@数码闲聊站 透露,原定三月份发布的华为新旗舰P70系列延期发布,预计4月份上市。
而博主@定焦数码 爆料,华为的P70系列在定位上已经超过了Mate60,成为了重要的旗舰系列之一。它肩负着重返影像领域顶尖的使命。那么这次P70会带来哪些令人惊艳的创新呢?
根据目前爆料的消息来看,华为P70系列将推出三个版本,其中P70和P70 Pro采用了三角形的摄像头模组设计,而P70 Art则采用了与上一代P60 Art相似的不规则形状设计。这样的外观是否好看见仁见智,但辨识度绝对拉满。
更新日志
- 凤飞飞《我们的主题曲》飞跃制作[正版原抓WAV+CUE]
- 刘嘉亮《亮情歌2》[WAV+CUE][1G]
- 红馆40·谭咏麟《歌者恋歌浓情30年演唱会》3CD[低速原抓WAV+CUE][1.8G]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[320K/MP3][193.25MB]
- 【轻音乐】曼托凡尼乐团《精选辑》2CD.1998[FLAC+CUE整轨]
- 邝美云《心中有爱》1989年香港DMIJP版1MTO东芝首版[WAV+CUE]
- 群星《情叹-发烧女声DSD》天籁女声发烧碟[WAV+CUE]
- 刘纬武《睡眠宝宝竖琴童谣 吉卜力工作室 白噪音安抚》[FLAC/分轨][748.03MB]
- 理想混蛋《Origin Sessions》[320K/MP3][37.47MB]
- 公馆青少年《我其实一点都不酷》[320K/MP3][78.78MB]
- 群星《情叹-发烧男声DSD》最值得珍藏的完美男声[WAV+CUE]
- 群星《国韵飘香·贵妃醉酒HQCD黑胶王》2CD[WAV]
- 卫兰《DAUGHTER》【低速原抓WAV+CUE】
- 公馆青少年《我其实一点都不酷》[FLAC/分轨][398.22MB]
- ZWEI《迟暮的花 (Explicit)》[320K/MP3][57.16MB]