added orientation support (via. sharp) + refactored .loadImages(..)...

Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
Alex A. Naanou 2016-06-03 04:46:51 +03:00
parent 9d02a2d15f
commit fa7f64871f
8 changed files with 161 additions and 39 deletions

View File

@ -13,6 +13,7 @@ var core = require('features/core')
require('features/base')
require('features/sort')
require('features/tags')
require('features/location')
require('features/history')
require('features/app')

View File

@ -269,7 +269,10 @@ var FullScreenControllsActions = actions.Actions({
// fullscreen....
.append($('<div>')
.addClass('button')
.html('&square;')
// square...
//.html('&square;')
// diagonal arrows...
.html('&#8601;')
.click(function(){ that.toggleFullScreen() }))
// close...
.append($('<div>')

View File

@ -62,16 +62,18 @@ var CLIActions = actions.Actions({
path = util.normalizePath(path)
return this.loadImages(path)
// save base index...
.then(function(){
// save base index...
that.saveIndex(path)
// make the previews...
that.makePreviews('all')
return that.saveIndex(path)
})
// make the previews...
.then(function(){
return that.makePreviews('all')
})
.then(function(){
//that.readAllMetadata()
that
return that
.sortImages()
// XXX for some reason this is not running from cli
.saveIndex(path)
@ -112,12 +114,13 @@ module.CLI = core.ImageGridFeatures.Feature({
var argv = process.argv
}
var package = requirejs('fs-extra').readJSONSync('./package.json')
// XXX this is not portable...
//var package = requirejs('fs-extra').readJSONSync('./package.json')
var cli = requirejs('commander')
cli
// XXX get the version from package.json...
.version(package.version)
//.version(package.version)
//.usage('[command] [options] ..')
.option('-v, --verbose', 'verbose mode', function(){

View File

@ -124,7 +124,7 @@ var FileSystemLoaderActions = actions.Actions({
'image-file-pattern': '*+(jpg|jpeg|png|JPG|JPEG|PNG)',
'image-file-read-stat': true,
'image-file-skip-previews': true,
'image-file-skip-previews': false,
// XXX if true and multiple indexes found, load only the first
// without merging...
@ -283,12 +283,70 @@ var FileSystemLoaderActions = actions.Actions({
})
}],
// Get image(s) previews...
//
// Load current image previews...
// .getPreviews()
// .getPreviews('current')
// -> promise
//
// Load previews for specific image...
// .getPreviews(gid)
// -> promise
//
// Load all image previews...
// .getPreviews('*')
// .getPreviews('all')
// -> promise
//
// Load previews that match glob pattern...
// .getPreviews(pattern)
// -> promise
// NOTE: this is useful for finding previews for example by
// image name, e.g. .getPreviews('*' + ig.image[gid].name)
//
// NOTE: this will override image .preview and .base_path
// NOTE: if multiple sets of previews are located this will use the
// last found and set image .base_path accordingly...
getPreviews: ['- File/',
function(pattern, path, images){
images = images || this.images
pattern = pattern == 'current' ? this.current + '*'
: pattern == 'all' ? '*'
// explicit gid...
: pattern in images ? pattern + '*'
// other pattern...
: pattern != null ? pattern
// default...
: this.current + '*'
path = path || this.location.path
var index_dir = this.config['index-dir']
return file.loadPreviews(path, pattern, null, index_dir)
.then(function(previews){
for(var l in previews){
var p = previews[l]
p && Object.keys(p).forEach(function(gid){
if(gid in images){
// XXX is this correct???
images[gid].base_path = pathlib.basename(l) == index_dir ?
pathlib.dirname(l)
: l
images[gid].preview = p[gid].preview
}
})
}
return images
})
}],
// Get images in path...
//
// This will:
// - get images from path
// - get basic stat data
// - get previews from path if they exist
// - get previews from path if they exist (.getPreviews(..))
//
// Returns: Images object
//
@ -349,24 +407,13 @@ var FileSystemLoaderActions = actions.Actions({
})
// load previews if they exist...
.then(function(imgs){
if(skip_preview_search){
return imgs
}
var index_dir = that.config['index-dir']
var index_path = path +'/'+ index_dir
return file.loadPreviews(index_path, null, index_dir)
.then(function(previews){
previews = previews[index_path]
previews && Object.keys(previews).forEach(function(gid){
if(gid in imgs){
imgs[gid].preview = previews[gid].preview
}
})
return imgs
})
return !skip_preview_search ?
//that.getPreviews('all', path, imgs)
that.getPreviews('all', index_path, imgs)
: imgs
})
}],

View File

@ -38,6 +38,33 @@ if(typeof(process) != 'undefined'){
var ensureDir = file.denodeify(fse.ensureDir)
}
function normalizeOrientation(orientation){
return {
orientation: ({
0: 0,
1: 0,
2: 0,
3: 180,
4: 0,
5: 90,
6: 90,
7: 90,
8: 270,
})[orientation],
flipped: ({
0: null,
1: null,
2: ['horizontal'],
3: null,
4: ['vertical'],
5: ['vertical'],
6: null,
7: ['horizontal'],
8: null,
})[orientation],
}
}
/*********************************************************************/
@ -162,11 +189,19 @@ var SharpActions = actions.Actions({
var post_handler = function(err, data){
if(data.status == 'done' || data.status == 'skipped'){
// get/make preview list...
var preview = that.images[data.gid].preview =
that.images[data.gid].preview || {}
var img = that.images[data.gid]
var preview = img.preview =
img.preview || {}
// save previews...
preview[data.res + 'px'] = data.path
var o = normalizeOrientation(data.orientation)
// save orientation...
img.orientation = o.orientation
img.flipped = o.flipped
that.markChanged(data.gid)
}
@ -233,6 +268,35 @@ module.Sharp = core.ImageGridFeatures.Feature({
isApplicable: function(){ return !!sharp },
handlers: [
// set orientation if not defined...
['updateImage',
function(_, gid){
var that = this
var img = this.images[gid]
if(img && img.orientation == null){
img.orientation = 0
sharp(this.getImagePath(gid))
.metadata()
.then(function(data){
var o = normalizeOrientation(data.orientation)
// NOTE: we need to set orientation to something
// or we'll check it again and again...
img.orientation = o.orientation || 0
img.flipped = o.flipped
that.markChanged(gid)
// update image to use the orientation...
// XXX this might be a source for recursion
// as it triggers .updateImage(..) again...
that.ribbons && that.ribbons.updateImage(gid)
})
}
}],
// XXX need to:
// - if image too large to set the preview to "loading..."
// - create previews...

View File

@ -31,10 +31,10 @@ module.PersistentTags = core.ImageGridFeatures.Feature({
tag: 'persistent-tags',
depends: [
// XXX
'base',
],
actions: TagCloudActions,
actions: PersistentTagsActions,
handlers: [],
})
@ -63,7 +63,7 @@ module.TagUI = core.ImageGridFeatures.Feature({
doc: '',
// XXX
tag: 'ui-tag',
tag: 'ui-tags',
depends: [
// XXX
],

View File

@ -127,8 +127,9 @@ function(base, index_dir, logger){
var listPreviews =
module.listPreviews =
function(base){
return gGlob(base +'/*px/*jpg')
function(base, img_pattern){
//return gGlob(base +'/*px/*jpg')
return gGlob(base +'/*px/'+(img_pattern || '*')+'.jpg')
}
@ -628,10 +629,11 @@ function(path, index_dir, from_date, logger){
// XXX handle errors....
var loadPreviews =
module.loadPreviews =
function(base, previews, index_dir, absolute_path){
function(base, pattern, previews, index_dir, absolute_path){
previews = previews || {}
index_dir = index_dir || INDEX_DIR
base = util.normalizePath(base)
pattern = pattern || '*'
// we got an explicit index....
if(pathlib.basename(base) == index_dir){
@ -642,7 +644,7 @@ function(base, previews, index_dir, absolute_path){
var images = previews[base]
listPreviews(base)
listPreviews(base, pattern)
// XXX handle errors....
//.on('error', function(err){
//})
@ -681,7 +683,7 @@ function(base, previews, index_dir, absolute_path){
//.on('error', function(err){
//})
.on('match', function(base){
queue.push(loadPreviews(base, previews, index_dir, absolute_path))
queue.push(loadPreviews(base, pattern, previews, index_dir, absolute_path))
})
.on('end', function(){
Promise.all(queue)

View File

@ -93,7 +93,8 @@ function(images, sizes, base_path, target_tpl, callback){
status: 'skipped',
gid: gid,
res: res,
path: rel
path: rel,
orientation: metadata.orientation,
})
return
@ -113,7 +114,8 @@ function(images, sizes, base_path, target_tpl, callback){
status: 'done',
gid: gid,
res: res,
path: rel
path: rel,
orientation: metadata.orientation,
})
})
})