Skip to content

Commit ef119b5

Browse files
authored
Merge pull request #16 from c0bra/feat/cluster-parse-frames.js
Use cluster module to process frames in parallel for parse-frames.js
2 parents 7cb4f16 + c92a2c0 commit ef119b5

File tree

3 files changed

+1541
-1439
lines changed

3 files changed

+1541
-1439
lines changed

cli.js

Lines changed: 160 additions & 160 deletions
Original file line numberDiff line numberDiff line change
@@ -60,29 +60,29 @@ const cli = meow(`
6060
$ dframe cat.png --frame "iPhone 6" --frame "iPhone 7"
6161
$ dframe cat.png --frame "iphone 6","iphone 7"
6262
`,
63-
{
64-
flags: {
65-
help: {
66-
alias: 'h',
67-
},
68-
delay: {
69-
default: 0,
70-
},
71-
devices: {
72-
default: false,
73-
},
74-
output: {
75-
type: 'string',
76-
alias: 'o',
77-
default: '.',
78-
},
79-
debug: {
80-
type: 'boolean',
81-
alias: 'd',
82-
default: false,
83-
},
63+
{
64+
flags: {
65+
help: {
66+
alias: 'h',
8467
},
85-
}
68+
delay: {
69+
default: 0,
70+
},
71+
devices: {
72+
default: false,
73+
},
74+
output: {
75+
type: 'string',
76+
alias: 'o',
77+
default: '.',
78+
},
79+
debug: {
80+
type: 'boolean',
81+
alias: 'd',
82+
default: false,
83+
},
84+
},
85+
}
8686
);
8787

8888
const framesRepo = cli.pkg.devDependencies['deviceframe-frames'];
@@ -147,19 +147,19 @@ if (cli.flags.frame) {
147147
*/
148148

149149
Promise.resolve()
150-
.then(init)
151-
.then(confirmInputs)
152-
.then(([files, urls]) => {
153-
return chooseFrames()
154-
.then(frames => [files, urls, frames]);
155-
})
156-
.then(([files, urls, frames]) => {
157-
return downloadFrames(frames)
158-
.then(frames => [files, urls, frames])
150+
.then(init)
151+
.then(confirmInputs)
152+
.then(([files, urls]) => {
153+
return chooseFrames()
154+
.then(frames => [files, urls, frames]);
155+
})
156+
.then(([files, urls, frames]) => {
157+
return downloadFrames(frames)
158+
.then(frames => [files, urls, frames])
159+
.catch(err => error(err));
160+
})
161+
.then(([files, urls, frames]) => frameImages(files, urls, frames))
159162
.catch(err => error(err));
160-
})
161-
.then(([files, urls, frames]) => frameImages(files, urls, frames))
162-
.catch(err => error(err));
163163

164164
/* ------------------------------------------------------------------------- */
165165

@@ -188,11 +188,11 @@ function confirmInputs() {
188188

189189
// Find image files to frame from input
190190
return globImageFiles(cli.input.filter(f => !isUrl(f)))
191-
.then(files => {
192-
if (files.length === 0 && urls.length === 0) error('No image files or urls specified', true);
191+
.then(files => {
192+
if (files.length === 0 && urls.length === 0) error('No image files or urls specified', true);
193193

194-
return [files, urls];
195-
});
194+
return [files, urls];
195+
});
196196
}
197197

198198
function chooseFrames() {
@@ -325,20 +325,20 @@ function downloadFrame(frame) {
325325
'user-agent': `deviceframe/${cli.pkg.version} (${cli.pkg.repo})`,
326326
},
327327
})
328-
.on('end', () => {
329-
bar.tick(100);
330-
resolve(frame);
331-
})
332-
.on('downloadProgress', progress => {
333-
console.log('progress.percent', progress.percent);
334-
bar.tick(progress.percent * 100);
335-
})
336-
.on('error', error => {
337-
if (fs.existsSync(frame.path)) fs.unlink(frame.path);
338-
console.log(require('util').inspect(error, { depth: null }));
339-
reject(error);
340-
})
341-
.pipe(fs.createWriteStream(frame.path));
328+
.on('end', () => {
329+
bar.tick(100);
330+
resolve(frame);
331+
})
332+
.on('downloadProgress', progress => {
333+
console.log('progress.percent', progress.percent);
334+
bar.tick(progress.percent * 100);
335+
})
336+
.on('error', error => {
337+
if (fs.existsSync(frame.path)) fs.unlink(frame.path);
338+
console.log(require('util').inspect(error, { depth: null }));
339+
reject(error);
340+
})
341+
.pipe(fs.createWriteStream(frame.path));
342342
});
343343
}
344344

@@ -369,134 +369,134 @@ function frameIt(img, frameConf) {
369369
const imgUrl = img;
370370
debug(`Checking for image: ${imgUrl}`);
371371
img = got(img, { encoding: null })
372-
.then(response => {
373-
if (typeis(response, ['image/*'])) return response.body;
374-
375-
// Scale image size for device pixel density
376-
const w = Math.floor(frameConf.frame.width / (frameConf.pixelRatio || 1));
377-
const h = Math.floor(frameConf.frame.height / (frameConf.pixelRatio || 1));
378-
const dim = [w, h].join('x');
379-
380-
const spinner = ora(`Screenshotting ${imgUrl} at ${dim}`).start();
381-
382-
// TODO: need to dynamically choose device user-agent from a list, or store them with the frames
383-
const ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1';
384-
const stream = screenshot(imgUrl, dim, { crop: false, userAgent: ua, delay: cli.flags.delay })
385-
.on('error', err => {
386-
spinner.fail();
387-
error(err);
388-
})
389-
.on('end', () => spinner.succeed());
390-
391-
const bufPromise = getStream.buffer(stream);
392-
// bufPromise.then(buf => {
393-
// fs.writeFileSync('test.png', buf, { encoding: 'binary' });
394-
// });
395-
396-
return Promise.all([bufPromise, w, h]);
397-
})
398-
.then(([buf, w, h]) => new Promise((resolve, reject) => {
399-
Jimp.read(buf)
400-
.then(lenna => {
401-
lenna.resize(w, Jimp.AUTO)
402-
.crop(0, 0, w, h)
403-
.getBuffer(Jimp.MIME_PNG, (err, result) => {
404-
if (err) return reject(err);
405-
406-
resolve(result);
407-
});
408-
});
409-
}))
410-
.catch(err => error(err));
372+
.then(response => {
373+
if (typeis(response, ['image/*'])) return response.body;
374+
375+
// Scale image size for device pixel density
376+
const w = Math.floor(frameConf.frame.width / (frameConf.pixelRatio || 1));
377+
const h = Math.floor(frameConf.frame.height / (frameConf.pixelRatio || 1));
378+
const dim = [w, h].join('x');
379+
380+
const spinner = ora(`Screenshotting ${imgUrl} at ${dim}`).start();
381+
382+
// TODO: need to dynamically choose device user-agent from a list, or store them with the frames
383+
const ua = 'Mozilla/5.0 (iPhone; CPU iPhone OS 9_1 like Mac OS X) AppleWebKit/601.1.46 (KHTML, like Gecko) Version/9.0 Mobile/13B143 Safari/601.1';
384+
const stream = screenshot(imgUrl, dim, { crop: false, userAgent: ua, delay: cli.flags.delay })
385+
.on('error', err => {
386+
spinner.fail();
387+
error(err);
388+
})
389+
.on('end', () => spinner.succeed());
390+
391+
const bufPromise = getStream.buffer(stream);
392+
// bufPromise.then(buf => {
393+
// fs.writeFileSync('test.png', buf, { encoding: 'binary' });
394+
// });
395+
396+
return Promise.all([bufPromise, w, h]);
397+
})
398+
.then(([buf, w, h]) => new Promise((resolve, reject) => {
399+
Jimp.read(buf)
400+
.then(lenna => {
401+
lenna.resize(w, Jimp.AUTO)
402+
.crop(0, 0, w, h)
403+
.getBuffer(Jimp.MIME_PNG, (err, result) => {
404+
if (err) return reject(err);
405+
406+
resolve(result);
407+
});
408+
});
409+
}))
410+
.catch(err => error(err));
411411
}
412412

413413
// Read in image and frame
414414
return Promise.resolve(img)
415-
.then(imgData => {
416-
const framePath = path.join(frameCacheDir, frameConf.relPath);
415+
.then(imgData => {
416+
const framePath = path.join(frameCacheDir, frameConf.relPath);
417417

418-
debug(`Reading in frame from ${framePath}`);
418+
debug(`Reading in frame from ${framePath}`);
419419

420-
return Promise.all([
421-
Jimp.read(framePath),
422-
Jimp.read(imgData),
423-
]);
424-
})
420+
return Promise.all([
421+
Jimp.read(framePath),
422+
Jimp.read(imgData),
423+
]);
424+
})
425425
// Resize largest image to fit the other
426-
.then(([frame, jimg]) => {
427-
debug('Resizing frame/image');
426+
.then(([frame, jimg]) => {
427+
debug('Resizing frame/image');
428428

429-
const frameImageWidth = frame.bitmap.width;
430-
const frameImageHeight = frame.bitmap.height;
429+
const frameImageWidth = frame.bitmap.width;
430+
const frameImageHeight = frame.bitmap.height;
431431

432-
const compLeftRatio = frameConf.frame.left / frameImageWidth;
433-
const compTopRatio = frameConf.frame.top / frameImageHeight;
432+
const compLeftRatio = frameConf.frame.left / frameImageWidth;
433+
const compTopRatio = frameConf.frame.top / frameImageHeight;
434434

435-
let compLeft = frameConf.frame.left;
436-
let compTop = frameConf.frame.top;
435+
let compLeft = frameConf.frame.left;
436+
let compTop = frameConf.frame.top;
437437

438-
const frameMax = Math.max(frameConf.frame.height, frameConf.frame.width);
439-
const jimgMax = Math.max(jimg.bitmap.height, jimg.bitmap.width);
438+
const frameMax = Math.max(frameConf.frame.height, frameConf.frame.width);
439+
const jimgMax = Math.max(jimg.bitmap.height, jimg.bitmap.width);
440440

441-
// Frame is bigger, size it down to source image
442-
if (frameMax > jimgMax) {
441+
// Frame is bigger, size it down to source image
442+
if (frameMax > jimgMax) {
443443
// Resize frame so shortest dimension matches source image. Source image overflow will be clipped
444-
let rH = frame.bitmap.height;
445-
let rW = frame.bitmap.width;
446-
if (frameConf.frame.height > frameConf.frame.width) {
447-
const ratio = jimg.bitmap.width / frameConf.frame.width;
448-
rW = Math.ceil(rW * ratio);
449-
rH = Jimp.AUTO;
444+
let rH = frame.bitmap.height;
445+
let rW = frame.bitmap.width;
446+
if (frameConf.frame.height > frameConf.frame.width) {
447+
const ratio = jimg.bitmap.width / frameConf.frame.width;
448+
rW = Math.ceil(rW * ratio);
449+
rH = Jimp.AUTO;
450+
} else {
451+
const ratio = jimg.bitmap.height / frameConf.frame.height;
452+
rH = Math.ceil(rH * ratio);
453+
rW = Jimp.AUTO;
454+
}
455+
456+
frame.resize(rW, rH);
457+
458+
// We resized the frame so there's a new compositing location on it
459+
compLeft = Math.ceil(frame.bitmap.width * compLeftRatio);
460+
compTop = Math.ceil(frame.bitmap.height * compTopRatio);
461+
462+
// Resize source image to fit new frame size
463+
const newFrameWidth = frameConf.frame.width * (frame.bitmap.width / frameImageWidth);
464+
const newFrameHeight = frameConf.frame.height * (frame.bitmap.height / frameImageHeight);
465+
466+
jimg.cover(newFrameWidth, newFrameHeight);
450467
} else {
451-
const ratio = jimg.bitmap.height / frameConf.frame.height;
452-
rH = Math.ceil(rH * ratio);
453-
rW = Jimp.AUTO;
454-
}
455-
456-
frame.resize(rW, rH);
457-
458-
// We resized the frame so there's a new compositing location on it
459-
compLeft = Math.ceil(frame.bitmap.width * compLeftRatio);
460-
compTop = Math.ceil(frame.bitmap.height * compTopRatio);
461-
462-
// Resize source image to fit new frame size
463-
const newFrameWidth = frameConf.frame.width * (frame.bitmap.width / frameImageWidth);
464-
const newFrameHeight = frameConf.frame.height * (frame.bitmap.height / frameImageHeight);
465-
466-
jimg.cover(newFrameWidth, newFrameHeight);
467-
} else {
468468
// Source image is bigger, size it down to frame
469469
// Resize frame so shortest dimension matches
470-
let rH = jimg.bitmap.height;
471-
let rW = jimg.bitmap.width;
472-
if (rH > rW) {
473-
rW = frameConf.frame.width;
474-
rH = Jimp.AUTO;
475-
} else {
476-
rH = frameConf.frame.height;
477-
rW = Jimp.AUTO;
470+
let rH = jimg.bitmap.height;
471+
let rW = jimg.bitmap.width;
472+
if (rH > rW) {
473+
rW = frameConf.frame.width;
474+
rH = Jimp.AUTO;
475+
} else {
476+
rH = frameConf.frame.height;
477+
rW = Jimp.AUTO;
478+
}
479+
480+
jimg.cover(frameConf.frame.width, frameConf.frame.height);
478481
}
479482

480-
jimg.cover(frameConf.frame.width, frameConf.frame.height);
481-
}
482-
483-
return [frame, jimg, { left: compLeft, top: compTop }, frameConf];
484-
})
485-
.then(([frame, jimg, compPos, frameConf]) => {
486-
debug(`Compositing... ${frameConf.frame.left} ${frameConf.frame.top}`);
483+
return [frame, jimg, { left: compLeft, top: compTop }, frameConf];
484+
})
485+
.then(([frame, jimg, compPos, frameConf]) => {
486+
debug(`Compositing... ${frameConf.frame.left} ${frameConf.frame.top}`);
487487

488-
// Create a canvas the same as the frame size for the screenshot to be placed on at the frame top/left coordinates
489-
const canvas = new Jimp(frame.bitmap.width, frame.bitmap.height);
490-
jimg = canvas.composite(jimg, compPos.left, compPos.top);
488+
// Create a canvas the same as the frame size for the screenshot to be placed on at the frame top/left coordinates
489+
const canvas = new Jimp(frame.bitmap.width, frame.bitmap.height);
490+
jimg = canvas.composite(jimg, compPos.left, compPos.top);
491491

492-
return jimg.composite(frame, 0, 0);
493-
})
494-
.then(composite => {
495-
debug('Saving...');
496-
composite.write(imgPath);
497-
console.log(chalk.bold('> ') + chalk.green('Wrote: ') + imgPath);
498-
})
499-
.catch(err => error(err));
492+
return jimg.composite(frame, 0, 0);
493+
})
494+
.then(composite => {
495+
debug('Saving...');
496+
composite.write(imgPath);
497+
console.log(chalk.bold('> ') + chalk.green('Wrote: ') + imgPath);
498+
})
499+
.catch(err => error(err));
500500
}
501501

502502
// function cacheSettings(settings) {

0 commit comments

Comments
 (0)