1 | var fs
|
2 | var path
|
3 | var glob
|
4 | var child_process
|
5 | var fileStuff
|
6 | var manifest
|
7 | var async
|
8 | var imageSize
|
9 |
|
10 |
|
11 | var exports = {
|
12 | images : images,
|
13 | ffmpegIsInstalled : ffmpegIsInstalled,
|
14 | fileIsImage : fileIsImage,
|
15 | processImage : processImage,
|
16 | percsToWidths : percsToWidths,
|
17 | fileIsImage : fileIsImage,
|
18 | addSizeToPath : addSizeToPath
|
19 | }
|
20 |
|
21 | module.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 |
|
46 | var imageExts = ['.jpg', '.jpeg', '.ico', '.gif', '.png',
|
47 | '.svg', '.bmp', '.psd', '.xcf', '.tiff']
|
48 |
|
49 |
|
50 |
|
51 |
|
52 | function 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 |
|
123 | function 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 |
|
153 | function 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 |
|
164 | function 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 |
|
171 | function fileIsImage(file) {
|
172 | var ext = path.extname(file).toLowerCase()
|
173 | return imageExts.indexOf(ext) !== -1
|
174 | }
|
175 |
|
176 | function 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 |
|
206 | function 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 |
|
213 | function 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 |
|
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 | }
|