mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-29 18:30:09 +00:00
cleanup...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
9c72528908
commit
c750895a4a
@ -185,440 +185,9 @@ var SharpActions = actions.Actions({
|
|||||||
// from filesystem.IndexFormat...
|
// from filesystem.IndexFormat...
|
||||||
},
|
},
|
||||||
|
|
||||||
// XXX either make this a session task or make this survive loading
|
|
||||||
// a new index...
|
|
||||||
// XXX revise return values...
|
// XXX revise return values...
|
||||||
// XXX make backup name pattern configurable...
|
// XXX make backup name pattern configurable...
|
||||||
// XXX CROP ready for crop support...
|
// XXX CROP ready for crop support...
|
||||||
_makeResizedImage: ['- Image/',
|
|
||||||
core.doc`Make resized image(s)...
|
|
||||||
|
|
||||||
.makeResizedImage(gid, size, path[, options])
|
|
||||||
.makeResizedImage(gids, size, path[, options])
|
|
||||||
-> promise
|
|
||||||
|
|
||||||
|
|
||||||
Image size formats:
|
|
||||||
500px - resize to make image's *largest* dimension 500 pixels (default).
|
|
||||||
500p - resize to make image's *smallest* dimension 500 pixels.
|
|
||||||
500 - same as 500px
|
|
||||||
|
|
||||||
|
|
||||||
options format:
|
|
||||||
{
|
|
||||||
// output image name / name pattern...
|
|
||||||
//
|
|
||||||
// NOTE: for multiple images this should be a pattern and not an
|
|
||||||
// explicit name...
|
|
||||||
// NOTE: if not given this defaults to: "%n"
|
|
||||||
name: null | <str>,
|
|
||||||
|
|
||||||
// image name pattern data...
|
|
||||||
//
|
|
||||||
// NOTE: for more info on pattern see: .formatImageName(..)
|
|
||||||
data: null | { .. },
|
|
||||||
|
|
||||||
// if true and image is smaller than size enlarge it...
|
|
||||||
//
|
|
||||||
// default: null / false
|
|
||||||
enlarge: null | true,
|
|
||||||
|
|
||||||
// overwrite, backup or skip (default) existing images...
|
|
||||||
//
|
|
||||||
// default: null / false
|
|
||||||
overwrite: null | true | 'backup',
|
|
||||||
|
|
||||||
// if true do not write an image if it's smaller than size...
|
|
||||||
//
|
|
||||||
// default: null / false
|
|
||||||
skipSmaller: null | true,
|
|
||||||
|
|
||||||
// XXX not implemented...
|
|
||||||
transform: ...,
|
|
||||||
crop: ...,
|
|
||||||
|
|
||||||
timestamp: ...,
|
|
||||||
logger: ...,
|
|
||||||
, }
|
|
||||||
|
|
||||||
|
|
||||||
NOTE: all options are optional.
|
|
||||||
NOTE: this will not overwrite existing images.
|
|
||||||
`,
|
|
||||||
core.sessionQueueHandler('Make resized image',
|
|
||||||
// get/normalize images...
|
|
||||||
// XXX if this is to be a global task (i.e. .queueHandler(..)) we'll
|
|
||||||
// need to get all the image data here...
|
|
||||||
// ...paths and orientation data...
|
|
||||||
function(queue, images, size, path, options){
|
|
||||||
// sanity check...
|
|
||||||
if(arguments.length < 4){
|
|
||||||
throw new Error('.makeResizedImage(..): '
|
|
||||||
+'need at least: images, size and path.') }
|
|
||||||
return [
|
|
||||||
(images == null || images == 'all') ?
|
|
||||||
this.data.getImages('all')
|
|
||||||
: images == 'current' ?
|
|
||||||
[this.current]
|
|
||||||
: images instanceof Array ?
|
|
||||||
images
|
|
||||||
: [images],
|
|
||||||
...[...arguments].slice(2),
|
|
||||||
]},
|
|
||||||
function(gid, size, path, options={}){
|
|
||||||
var that = this
|
|
||||||
|
|
||||||
// sizing...
|
|
||||||
var fit =
|
|
||||||
typeof(size) == typeof('str') ?
|
|
||||||
(size.endsWith('px') ?
|
|
||||||
'inside'
|
|
||||||
: size.endsWith('p') ?
|
|
||||||
'outside'
|
|
||||||
: 'inside')
|
|
||||||
: 'inside'
|
|
||||||
size = parseInt(size)
|
|
||||||
// options...
|
|
||||||
var {
|
|
||||||
// naming...
|
|
||||||
name,
|
|
||||||
data,
|
|
||||||
|
|
||||||
// file handling...
|
|
||||||
enlarge,
|
|
||||||
skipSmaller,
|
|
||||||
overwrite,
|
|
||||||
|
|
||||||
// transformations...
|
|
||||||
transform,
|
|
||||||
// XXX CROP not implemented...
|
|
||||||
//crop,
|
|
||||||
|
|
||||||
timestamp,
|
|
||||||
//logger,
|
|
||||||
} = options
|
|
||||||
// defaults...
|
|
||||||
name = name || '%n'
|
|
||||||
transform = transform === undefined ?
|
|
||||||
true
|
|
||||||
: transform
|
|
||||||
timestamp = timestamp || Date.timeStamp()
|
|
||||||
|
|
||||||
// backup...
|
|
||||||
// XXX make backup name pattern configurable...
|
|
||||||
var backupName = function(to){
|
|
||||||
var i = 0
|
|
||||||
while(fse.existsSync(`${to}.${timestamp}.bak`+ (i || ''))){
|
|
||||||
i++ }
|
|
||||||
return `${to}.${timestamp}.bak`+ (i || '') }
|
|
||||||
|
|
||||||
// skip non-images...
|
|
||||||
if(!['image', null, undefined]
|
|
||||||
.includes(this.images[gid].type)){
|
|
||||||
// XXX what should we return???
|
|
||||||
return Promise.resolve() }
|
|
||||||
|
|
||||||
// paths...
|
|
||||||
var source = this.getImagePath(gid)
|
|
||||||
var to = pathlib.resolve(
|
|
||||||
this.location.path,
|
|
||||||
pathlib.join(
|
|
||||||
path,
|
|
||||||
// if name is not a pattern do not re-format it...
|
|
||||||
name.includes('%') ?
|
|
||||||
this.formatImageName(name, gid, data || {})
|
|
||||||
: name))
|
|
||||||
|
|
||||||
var img = sharp(source)
|
|
||||||
return (skipSmaller ?
|
|
||||||
// skip if smaller than size...
|
|
||||||
img
|
|
||||||
.metadata()
|
|
||||||
.then(function(m){
|
|
||||||
// skip...
|
|
||||||
if((fit == 'inside'
|
|
||||||
&& Math.max(m.width, m.height) < size)
|
|
||||||
|| (fit == 'outside'
|
|
||||||
&& Math.min(m.width, m.height) < size)){
|
|
||||||
return }
|
|
||||||
// continue...
|
|
||||||
return img })
|
|
||||||
: Promise.resolve(img))
|
|
||||||
// prepare to write...
|
|
||||||
.then(function(img){
|
|
||||||
return img
|
|
||||||
&& ensureDir(pathlib.dirname(to))
|
|
||||||
.then(function(){
|
|
||||||
// handle existing image...
|
|
||||||
if(fse.existsSync(to)){
|
|
||||||
// rename...
|
|
||||||
if(overwrite == 'backup'){
|
|
||||||
fse.renameSync(to, backupName(to))
|
|
||||||
// remove...
|
|
||||||
} else if(overwrite){
|
|
||||||
fse.removeSync(to)
|
|
||||||
// skip...
|
|
||||||
} else {
|
|
||||||
return Promise.reject('target exists') } }
|
|
||||||
|
|
||||||
// write...
|
|
||||||
return img
|
|
||||||
.clone()
|
|
||||||
// handle transform (.orientation / .flip) and .crop...
|
|
||||||
.run(function(){
|
|
||||||
var img = that.images[gid]
|
|
||||||
if(transform && (img.orientation || img.flipped)){
|
|
||||||
img.orientation
|
|
||||||
&& this.rotate(img.orientation)
|
|
||||||
img.flipped
|
|
||||||
&& img.flipped.includes('horizontal')
|
|
||||||
&& this.flip() }
|
|
||||||
img.flipped
|
|
||||||
&& img.flipped.includes('vertical')
|
|
||||||
&& this.flop()
|
|
||||||
// XXX CROP
|
|
||||||
//if(crop){
|
|
||||||
// // XXX
|
|
||||||
//}
|
|
||||||
})
|
|
||||||
.resize({
|
|
||||||
width: size,
|
|
||||||
height: size,
|
|
||||||
fit: fit,
|
|
||||||
withoutEnlargement: !enlarge,
|
|
||||||
})
|
|
||||||
.withMetadata()
|
|
||||||
.toFile(to)
|
|
||||||
.then(function(){
|
|
||||||
// XXX what should we return???
|
|
||||||
return to }) }) }) })],
|
|
||||||
|
|
||||||
_makeResizedImage2: ['- Image/',
|
|
||||||
core.doc`Make resized image(s)...
|
|
||||||
|
|
||||||
.makeResizedImage(gid, size, path[, options])
|
|
||||||
.makeResizedImage(gids, size, path[, options])
|
|
||||||
-> promise
|
|
||||||
|
|
||||||
|
|
||||||
Image size formats:
|
|
||||||
500px - resize to make image's *largest* dimension 500 pixels (default).
|
|
||||||
500p - resize to make image's *smallest* dimension 500 pixels.
|
|
||||||
500 - same as 500px
|
|
||||||
|
|
||||||
|
|
||||||
options format:
|
|
||||||
{
|
|
||||||
// output image name / name pattern...
|
|
||||||
//
|
|
||||||
// NOTE: for multiple images this should be a pattern and not an
|
|
||||||
// explicit name...
|
|
||||||
// NOTE: if not given this defaults to: "%n"
|
|
||||||
name: null | <str>,
|
|
||||||
|
|
||||||
// image name pattern data...
|
|
||||||
//
|
|
||||||
// NOTE: for more info on pattern see: .formatImageName(..)
|
|
||||||
data: null | { .. },
|
|
||||||
|
|
||||||
// if true and image is smaller than size enlarge it...
|
|
||||||
//
|
|
||||||
// default: null / false
|
|
||||||
enlarge: null | true,
|
|
||||||
|
|
||||||
// overwrite, backup or skip (default) existing images...
|
|
||||||
//
|
|
||||||
// default: null / false
|
|
||||||
overwrite: null | true | 'backup',
|
|
||||||
|
|
||||||
// if true do not write an image if it's smaller than size...
|
|
||||||
//
|
|
||||||
// default: null / false
|
|
||||||
skipSmaller: null | true,
|
|
||||||
|
|
||||||
// XXX not implemented...
|
|
||||||
transform: ...,
|
|
||||||
crop: ...,
|
|
||||||
|
|
||||||
timestamp: ...,
|
|
||||||
logger: ...,
|
|
||||||
, }
|
|
||||||
|
|
||||||
|
|
||||||
NOTE: all options are optional.
|
|
||||||
NOTE: this will not overwrite existing images.
|
|
||||||
`,
|
|
||||||
core.queueHandler('Make resized image',
|
|
||||||
// queue the image data...
|
|
||||||
// NOTE: after this runs we should be completely independent
|
|
||||||
// of the current index...
|
|
||||||
// XXX for a very large number of images this can block for
|
|
||||||
// a substantial amount of time...
|
|
||||||
function(queue, images, size, path, options){
|
|
||||||
var that = this
|
|
||||||
// sanity check...
|
|
||||||
if(arguments.length < 4){
|
|
||||||
throw new Error('.makeResizedImage(..): '
|
|
||||||
+'need at least: images, size and path.') }
|
|
||||||
// options...
|
|
||||||
var {
|
|
||||||
name,
|
|
||||||
data,
|
|
||||||
} = options || {}
|
|
||||||
name = name || '%n'
|
|
||||||
// [source, to, image], ...args
|
|
||||||
return [
|
|
||||||
((images == null || images == 'all') ?
|
|
||||||
this.data.getimages('all')
|
|
||||||
: images == 'current' ?
|
|
||||||
[this.current]
|
|
||||||
: images instanceof array ?
|
|
||||||
images
|
|
||||||
: [images])
|
|
||||||
.map(function(gid){
|
|
||||||
var image = that.images[gid]
|
|
||||||
// skip non-images...
|
|
||||||
if(!image || !['image', null, undefined]
|
|
||||||
.includes(image.type)){
|
|
||||||
return [] }
|
|
||||||
return [[
|
|
||||||
// source...
|
|
||||||
that.getimagepath(gid),
|
|
||||||
// target...
|
|
||||||
pathlib.resolve(
|
|
||||||
that.location.path,
|
|
||||||
pathlib.join(
|
|
||||||
path,
|
|
||||||
// if name is not a pattern do not re-format it...
|
|
||||||
name.includes('%') ?
|
|
||||||
that.formatimagename(name, gid, data || {})
|
|
||||||
: name)),
|
|
||||||
// image data...
|
|
||||||
// note: we include only the stuff we need...
|
|
||||||
{
|
|
||||||
orientation: image.orientation,
|
|
||||||
flipped: image.flipped,
|
|
||||||
// crop...
|
|
||||||
},
|
|
||||||
]] })
|
|
||||||
.flat(),
|
|
||||||
...[...arguments].slice(2),
|
|
||||||
]},
|
|
||||||
function([source, to, image], size, _, options={}){
|
|
||||||
// sizing...
|
|
||||||
var fit =
|
|
||||||
typeof(size) == typeof('str') ?
|
|
||||||
(size.endsWith('px') ?
|
|
||||||
'inside'
|
|
||||||
: size.endsWith('p') ?
|
|
||||||
'outside'
|
|
||||||
: 'inside')
|
|
||||||
: 'inside'
|
|
||||||
size = parseInt(size)
|
|
||||||
// options...
|
|
||||||
var {
|
|
||||||
enlarge,
|
|
||||||
skipSmaller,
|
|
||||||
overwrite,
|
|
||||||
transform,
|
|
||||||
timestamp,
|
|
||||||
backupImagePattern,
|
|
||||||
//logger,
|
|
||||||
} = options
|
|
||||||
// defaults...
|
|
||||||
transform = transform === undefined ?
|
|
||||||
true
|
|
||||||
: transform
|
|
||||||
timestamp = timestamp || Date.timeStamp()
|
|
||||||
// backup by default...
|
|
||||||
overwrite = overwrite === undefined ?
|
|
||||||
'backup'
|
|
||||||
: overwrite
|
|
||||||
backupImagePattern =
|
|
||||||
(backupImagePattern
|
|
||||||
|| '${PATH}.${TIMESTAMP}${COUNT}.bak')
|
|
||||||
.replace(/\${PATH}|$PATH/, to)
|
|
||||||
.replace(/\${TIMESTAMP}|$TIMESTAMP/, timestamp)
|
|
||||||
// backup...
|
|
||||||
// NOTE: we are doing the check at the very last moment and
|
|
||||||
// not here to avoid race conditions as much as practical...
|
|
||||||
var backupName = function(){
|
|
||||||
var i = 0
|
|
||||||
var n
|
|
||||||
do{
|
|
||||||
n = backupImagePattern
|
|
||||||
.replace(/\${COUNT}|$COUNT/, i++ ? '.'+i : i)
|
|
||||||
} while(fse.existsSync(n))
|
|
||||||
return n }
|
|
||||||
|
|
||||||
var img = sharp(source)
|
|
||||||
return (skipSmaller ?
|
|
||||||
// skip if smaller than size...
|
|
||||||
img
|
|
||||||
.metadata()
|
|
||||||
.then(function(m){
|
|
||||||
// skip...
|
|
||||||
if((fit == 'inside'
|
|
||||||
&& Math.max(m.width, m.height) < size)
|
|
||||||
|| (fit == 'outside'
|
|
||||||
&& Math.min(m.width, m.height) < size)){
|
|
||||||
return }
|
|
||||||
// continue...
|
|
||||||
return img })
|
|
||||||
: Promise.resolve(img))
|
|
||||||
// prepare to write...
|
|
||||||
.then(function(img){
|
|
||||||
return img
|
|
||||||
&& ensureDir(pathlib.dirname(to))
|
|
||||||
.then(function(){
|
|
||||||
// handle existing image...
|
|
||||||
if(fse.existsSync(to)){
|
|
||||||
// rename...
|
|
||||||
if(overwrite == 'backup'){
|
|
||||||
fse.renameSync(to, backupName(to))
|
|
||||||
// remove...
|
|
||||||
} else if(overwrite){
|
|
||||||
fse.removeSync(to)
|
|
||||||
// skip...
|
|
||||||
} else {
|
|
||||||
return Promise.reject('target exists') } }
|
|
||||||
// write...
|
|
||||||
return img
|
|
||||||
.clone()
|
|
||||||
// handle transform (.orientation / .flip) and .crop...
|
|
||||||
.run(function(){
|
|
||||||
if(transform && (image.orientation || image.flipped)){
|
|
||||||
image.orientation
|
|
||||||
&& this.rotate(image.orientation)
|
|
||||||
image.flipped
|
|
||||||
&& image.flipped.includes('horizontal')
|
|
||||||
&& this.flip() }
|
|
||||||
image.flipped
|
|
||||||
&& image.flipped.includes('vertical')
|
|
||||||
&& this.flop()
|
|
||||||
// XXX CROP
|
|
||||||
//if(crop){
|
|
||||||
// // XXX
|
|
||||||
//}
|
|
||||||
})
|
|
||||||
.resize({
|
|
||||||
width: size,
|
|
||||||
height: size,
|
|
||||||
fit: fit,
|
|
||||||
withoutEnlargement: !enlarge,
|
|
||||||
})
|
|
||||||
.withMetadata()
|
|
||||||
.toFile(to)
|
|
||||||
.then(function(){
|
|
||||||
// XXX what should we return???
|
|
||||||
return to }) }) }) })],
|
|
||||||
|
|
||||||
// XXX we need to split this into two stages:
|
|
||||||
// - session queue handler
|
|
||||||
// - global queue handler
|
|
||||||
// i.e. call the second queue generator when the first one completes...
|
|
||||||
// or in other works chain queues -- essentially this is like
|
|
||||||
// calling .then(..) on a queue but doing it at definition...
|
|
||||||
makeResizedImage: ['- Image/',
|
makeResizedImage: ['- Image/',
|
||||||
core.doc`Make resized image(s)...
|
core.doc`Make resized image(s)...
|
||||||
|
|
||||||
|
|||||||
Loading…
x
Reference in New Issue
Block a user