UNPKG

5.25 kBJavaScriptView Raw
1var fs
2var path
3var glob
4var child_process
5var fileStuff
6var manifest
7var async
8var imageSize
9
10
11var exports = {
12 images : images,
13 ffmpegIsInstalled : ffmpegIsInstalled,
14 fileIsImage : fileIsImage,
15 processImage : processImage,
16 percsToWidths : percsToWidths,
17 fileIsImage : fileIsImage,
18 addSizeToPath : addSizeToPath
19}
20
21module.exports = function(gulpManifest, deps) {
22
23 if(deps) {
24 fs = deps.fs
25 path = deps.path
26 glob = deps.glob
27 async = deps.async
28 child_process = deps.child_process
29 fileStuff = deps.fileStuff
30 imageSize = deps.imageSize
31 }
32 else {
33 fs = require('fs')
34 path = require('path')
35 glob = require('glob')
36 async = require('async')
37 child_process = require('child_process')
38 fileStuff = require(path.dirname(__filename) + '/fileStuff.js')()
39 imageSize = require('image-size')
40 }
41
42 manifest = gulpManifest
43 return exports
44}
45
46var imageExts = ['.jpg', '.jpeg', '.ico', '.gif', '.png',
47 '.svg', '.bmp', '.psd', '.xcf', '.tiff']
48
49//-------------------------------------------------
50
51
52function images(pkgIndex, destIndex, cb) {
53
54 var src = manifest[pkgIndex]["src"]
55 var dest = manifest[pkgIndex]["dest"][destIndex]
56 if(!src.images || (Array.isArray(src.images) && src.images.length === 0)) {
57 cb()
58 return
59 }
60
61 ffmpegIsInstalled(function(err){
62
63 if(err) {
64 cb("You need to install ffmpeg in order to process images")
65 return
66 }
67
68 var imagesList = []
69 if(Array.isArray(src.images)) {
70 for(var i in src.images) {
71 imagesList.push(src.images[i])
72 }
73 }
74 else imagesList.push(src.images)
75
76 var mRecord = fileStuff.openModificationsRecord()
77
78 async.each(imagesList, function(imageSrc, cb1){
79
80 var srcBase = src.directory
81 if(srcBase !== "") srcBase += "/"
82
83 if(Array.isArray(imageSrc.glob)) {
84
85 async.each(imageSrc.glob, function(fileglob, cb2){
86 var allFiles = glob.sync(srcBase + fileglob)
87 if(allFiles.length === 0) {
88 cb2()
89 }
90 else {
91 imageProcessLoop(allFiles, imageSrc, src, dest, mRecord, cb2)
92 }
93
94 },
95 function(err){
96 if(err) cb1(err)
97 else cb1()
98 })
99 }
100 else {
101 var allFiles = glob.sync(srcBase + imageSrc.glob)
102 if(allFiles.length === 0){
103 cb1()
104 }
105 else {
106 imageProcessLoop(allFiles, imageSrc, src, dest, mRecord, cb1)
107 }
108 }
109
110 }, function(err){
111 if(err) cb(err)
112 else {
113 console.log("IMAGE PROCESSING FINISHED")
114 fileStuff.closeModificationsRecord(mRecord)
115 cb()
116 }
117 })
118
119 })
120}
121
122
123function imageProcessLoop(files, imageSrc, src, dest, mRecord, cb) {
124
125 async.each(files, function(file, cb1) {
126
127 var fileOut = fileStuff.getDestPath(file, src.directory, dest.directory)
128
129 if(!fileStuff.fileIsDirectory(file)) {
130
131 var fileNeedsUpdating = imagesNeedUpdating(mRecord, file, fileOut, imageSrc.sizes)
132 var isImage = exports.fileIsImage(file)
133
134 if(fileNeedsUpdating && isImage) {
135 fileStuff.mkdirIfNotExist(fileOut)
136 console.log("Processing image: ", file)
137 processImage(file, fileOut, imageSrc.sizes, cb1)
138 }
139 else {
140 cb1()
141 }
142 }
143 else {
144 fileStuff.mkdirIfNotExist(fileOut)
145 cb1()
146 }
147 }, function(err){
148 if(err) cb(err)
149 else cb()
150 })
151}
152
153function imagesNeedUpdating(mRecord, fileIn, fileOut, sizes){
154
155 var needsUpdating = false
156
157 for(var size in sizes) {
158 var newFileOut = addSizeToPath(fileOut, size)
159 if(fileStuff.fileNeedsUpdating(mRecord, fileIn, newFileOut)) needsUpdating = true
160 }
161 return needsUpdating
162}
163
164function ffmpegIsInstalled(cb) {
165 child_process.exec('ffmpeg -version', function(error, stdout, stdin){
166 if(error) cb("ffmpeg not installed")
167 else cb()
168 })
169}
170
171function fileIsImage(file) {
172 var ext = path.extname(file).toLowerCase()
173 return imageExts.indexOf(ext) !== -1
174}
175
176function percsToWidths(file, sizes) {
177
178 var output = []
179 var imgWidth = imageSize(file).width
180
181 for(var size in sizes) {
182
183 var fract
184 if(typeof sizes[size] === "number") {
185 fract = sizes[size]
186 }
187 else if (typeof sizes[size] === "string") {
188 if(sizes[size].indexOf('%') !== -1) {
189 fract = sizes[size].replace(/%/, '')/100
190 }
191 else {
192 fract = sizes[size]
193 }
194 }
195 else {
196 throw new Error("Image size is not understood")
197 }
198 output.push({
199 name: size,
200 width: Math.floor(imgWidth*fract)
201 })
202 }
203 return output
204}
205
206function addSizeToPath(file, sizeName) {
207 var ext = path.extname(file)
208 file = file.slice(0, -1*ext.length)
209 file += "_" + sizeName + ext
210 return file.replace(/\\/g, '/')
211}
212
213function processImage(src, dest, sizes, cb) {
214
215 sizes = percsToWidths(src, sizes)
216
217 async.each(sizes, function(size, cb1){
218
219 var base = process.cwd()
220 if(base !== "") base += '/'
221
222 var fileIn = (base + src).replace(/\\/g, '/')
223 var fileOut = (base + addSizeToPath(dest, size.name)).replace(/\\/g, '/')
224
225 var cmd = 'ffmpeg -i "' + fileIn + '" ' +
226 '-vf scale=' + size.width + ':-1 ' +
227 '"' + fileOut + '"'
228
229 //console.log(cmd)
230
231 child_process.exec(cmd, function(err, stdout, stdin){cb1()})
232
233 }, function(err){
234 if(err) cb(err)
235 else cb()
236 })
237}