調用imagemagick作響應圖片

設計出圖後常常須要改下尺寸放在別的項目上使用,每次都是設計手工處理,其實圖片服務能夠作更多事情,好比藉助強大的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 }
相關文章
相關標籤/搜索