設計出圖後常常須要改下尺寸放在別的項目上使用,每次都是設計手工處理,其實圖片服務能夠作更多事情,好比藉助強大的im,能夠經過url控制圖片尺寸php
1 var childProcess = require('child_process') 2 var path = require('path') 3 ,http = require('http') 4 ,fs = require('fs') 5 6 const dns_host = 'xxx.net' //圖片源站地址 7 const PATH_IMGS = '/home/work/demo/images' //目錄存放 8 const PATH_IMG_TMP = '/home/work/demo/images' //臨時目錄 9 //圖片尺寸參數 10 // /pic/_hd/cd/19/d6d821de10662d5352ff2d6bbaf2_960_420.cj.100x100x15.jpg 11 const REG_RESIZE_OPT = /\.(\d+)?x(\d+[\!\>\<]?)?x(\d+)?\.jpg/ 12 //圖片質量 默認85 13 // /pic/_hd/cd/19/d6d821de10662d5352ff2d6bbaf2_960_420.cj.q100.100x100x15.jpg 14 const REG_QUALITY_OPT = /\.q(\d+)\.jpg/ //圖片質量參數 15 16 http.createServer(function(req, res) { 17 var imgurl = req.url 18 ,cdn_path = imgurl 19 var options = cdn_path.match(REG_RESIZE_OPT ) 20 var img_suffix = path.extname(cdn_path) 21 var opt_img = {} 22 if (options){ 23 opt_img = 24 { 25 "width" : options[1] || '' 26 ,"height" : options[2] || '' 27 ,"mode" : options[3] | 0 || 1 28 ,"imgurl" : imgurl 29 } 30 cdn_path = cdn_path.replace(REG_RESIZE_OPT, img_suffix) 31 } 32 33 options = cdn_path.match(REG_QUALITY_OPT) 34 if (options) { 35 opt_img.quality = options[1] | 0 36 cdn_path = cdn_path.replace(REG_QUALITY_OPT, img_suffix) 37 } 38 opt_img.quality = opt_img.quality || 85 39 if (opt_img.quality >= 100) delete opt_img.quality 40 41 42 http.get('http://' + dns_host + cdn_path , function(response){ 43 //由於圖片size變了 去掉content-length 44 delete response.headers['content-length'] 45 res.writeHead(response.statusCode , response.headers) 46 if (200 !== response.statusCode) return response.pipe(res) 47 48 49 50 var file_tmp = path.resolve(PATH_IMG_TMP , 'tmp_' + (+new Date).toString(24) + (img_suffix || '')) 51 //抓取遠程圖片 臨時存圖 52 var writeStream = fs.createWriteStream(file_tmp) 53 response.pipe(writeStream) 54 55 writeStream.on('error' ,function(err){ 56 console.log('err' , err) 57 res.end(err.toString()) 58 }) 59 60 response.on('end' ,function(err){ 61 imgWorker(file_tmp , opt_img , (err ,imgsrc) => { 62 if (err) return res.end(err.toString()) 63 imgsrc = imgsrc || file_tmp 64 var read_stream = fs.createReadStream(imgsrc) 65 read_stream.pipe(res) 66 read_stream.on('end' ,function(){ 67 fs.unlink(file_tmp) 68 }) 69 }) 70 }) 71 72 73 }) 74 }).listen(8791) //web服務端口 75 76 function mkdirp(p){ 77 p = path.dirname(p) 78 if (fs.existsSync(p)) return 79 80 p = p.split('/') 81 var pathnow = '' 82 p.forEach(function(pi){ 83 pathnow += pi + '/' 84 if (!fs.existsSync(pathnow) ) fs.mkdirSync(pathnow) 85 }) 86 87 } 88 89 function imgWorker( file_tmp ,opt ,cbk){ 90 opt = opt || {} 91 92 93 const bindPath = '/usr/local/ImageMagick/bin/' 94 var bindIdentity = bindPath + 'identify' 95 96 /* 97 * mode 0 等比 98 * mode 1 剪切 99 * mode 2 壓縮填充 100 * */ 101 if (!opt.height) opt.mode = 0 102 103 convert() 104 105 function convert(){ 106 var binConvert = bindPath + 'convert' 107 var img_save_path = PATH_IMGS + opt.imgurl 108 mkdirp(img_save_path) 109 /* 110 convert -resize 1024 file.jpg newfile.jpg 111 獲得圖片寬爲1024,高根據原始圖片比例計算而來 112 113 convert -resize x768 file.jpg newfile.jpg 114 獲得的圖片高位768,寬根據原始圖片比例計算而來 115 116 convert -resize 1024×768! file.jpg newfile.jpg 117 固定寬高縮放,不考慮原是圖寬高的比例,把圖片縮放到指定大小。 118 119 convert -resize 「1024×768>」 file.jpg newfile.jpg 120 只有當src.jpg的寬大於1024或高大於768時候,才進行縮小處理,不然生成newfile.jpg和file.jpg具備同樣的尺寸。 121 122 convert -resize 「1024×768<」 file.jpg newfile.jpg 123 只有當src.jpg的寬小於1024或高小於768時候,才進行放大處理,不然生成newfile.jpg和file.jpg具備同樣的尺寸。 124 125 http://www.imagemagick.org/discourse-server/viewtopic.php?t=18545 126 127 */ 128 129 var childArgs = [] 130 131 /* 132 * NorthWest, North, NorthEast, West, Center, East, SouthWest, South, SouthEast 133 * NorthWest是左上角對齊 ,SouthEast是右下角對齊 134 * 經過resize參數第二位能夠控制對應對齊方式 默認Center 居中 135 */ 136 if (opt.mode) { 137 var _m = opt.mode.toString() 138 var gravity = ['NorthWest', 'North', 'NorthEast', 'West' 139 , 'Center', 'East', 'SouthWest', 'South', 'SouthEast'] 140 [(_m.slice(1,2) || 4) | 0] 141 var color = ['' ,'white' ,'black'][(_m.slice(2,3) || 0) | 0] 142 opt.mode = _m.slice(0,1) | 0 143 } 144 switch (opt.mode){ 145 case 2: 146 /* 147 * mode爲2x 圖片壓縮填入指定尺寸 底色填充 148 * you can resize to the larger dimension and then pad the image 149 * convert image -resize "275x275" -gravity center -background white -extent 275x275 resultimage 150 */ 151 childArgs.push('-resize') 152 childArgs.push(opt.width + 'x' + opt.height ) 153 childArgs.push('-gravity') 154 childArgs.push(gravity) 155 if (color) { 156 childArgs.push('-background') 157 childArgs.push(color) 158 } 159 160 childArgs.push('-extent') 161 childArgs.push( opt.width + 'x' + opt.height ) 162 break 163 case 1: 164 /* 165 * mode爲1x 圖片拉伸 溢出剪切 166 */ 167 var cut = '+0+0' 168 childArgs.push('-resize') 169 childArgs.push(opt.width + 'x' + opt.height + '^') 170 childArgs.push('-gravity') 171 childArgs.push(gravity) 172 173 childArgs.push('-crop') 174 childArgs.push( opt.width + 'x' + opt.height + cut ) 175 176 break 177 default: 178 /* 179 * 原圖等比例縮放 比例不符合時以原圖爲準 180 */ 181 var opt_size = opt.width || '' 182 if (opt.height) opt_size += 'x' + opt.height 183 if (opt_size){ 184 childArgs.push('-resize') 185 childArgs.push(opt_size) 186 } 187 } 188 //去除元數據 相機信息 ps信息等 189 childArgs.push('+profile') 190 childArgs.push('"*"') 191 childArgs.push('-strip') 192 193 if (opt.quality){ 194 childArgs.push('-quality') 195 childArgs.push(opt.quality) 196 } 197 198 199 childArgs.push(file_tmp) 200 childArgs.push(img_save_path) 201 202 console.log(childArgs) 203 204 childProcess.execFile(binConvert, childArgs, function(err, stdout, stderr) { 205 err && console.log(err) 206 cbk(err , img_save_path) 207 }) 208 } 209 210 }
node前端是nginx 對處理過的圖片就能夠直接使用了前端
1 server { 2 listen 80; 3 server_name xxx.com; 4 5 location /favicon.ico { 6 return 418; 7 } 8 9 location / { 10 root /home/work/demo/images ; 11 try_files $uri $uri/ @router; 12 13 } 14 location @router { 15 proxy_pass http://127.0.0.1:8791; 16 } 17 }