mirror of
https://github.com/flynx/ImageGrid.git
synced 2025-10-28 18:00:09 +00:00
read orientation from file (via vips) and several improvements to preview loading/creating, needs revision and tuning...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
parent
efbdac7e9d
commit
37d89854b8
@ -1,7 +1,7 @@
|
||||
#=======================================================================
|
||||
|
||||
__version__ = '''0.0.01'''
|
||||
__sub_version__ = '''20130706023530'''
|
||||
__sub_version__ = '''20130707233437'''
|
||||
__copyright__ = '''(c) Alex A. Naanou 2011'''
|
||||
|
||||
|
||||
@ -311,7 +311,7 @@ def build_images(path, config=CONFIG, gid_generator=hash_gid, verbosity=0):
|
||||
8: 270,
|
||||
}[orientation],
|
||||
'flipped': {
|
||||
0: 0,
|
||||
0: None,
|
||||
1: None,
|
||||
2: ['horizontal'],
|
||||
3: None,
|
||||
|
||||
@ -125,6 +125,54 @@ if(window.CEF_dumpJSON != null){
|
||||
})
|
||||
}
|
||||
|
||||
// XXX this uses vips...
|
||||
// XXX handle errors...
|
||||
// NOTE: source can be either gid or a path...
|
||||
window._getImageSize = function(dimension, source){
|
||||
if(source in IMAGES){
|
||||
var img = IMAGES[gid]
|
||||
var source = normalizePath(img.path)
|
||||
}
|
||||
var getter = $.Deferred()
|
||||
if(dimension == 'max' || dimension == 'min'){
|
||||
$.when(
|
||||
_getImageSize('width', source),
|
||||
_getImageSize('height', source))
|
||||
.done(function(w, h){
|
||||
getter.resolve(Math[dimension](w, h))
|
||||
})
|
||||
|
||||
} else if(dimension == 'width' || dimension == 'height') {
|
||||
var cmd = 'vips im_header_int $DIM "$IN"'
|
||||
.replace(/\$IN/g, source.replace(fp, ''))
|
||||
.replace(/\$DIM/g, dimension)
|
||||
proc.exec(cmd, function(error, stdout, stderr){
|
||||
getter.resolve(parseInt(stdout.trim()))
|
||||
})
|
||||
|
||||
} else {
|
||||
// wrong dimension...
|
||||
return getter.reject('unknown dimension:' + dimension)
|
||||
}
|
||||
|
||||
return getter
|
||||
}
|
||||
|
||||
// NOTE: source can be either gid or a path...
|
||||
window.getImageOrientation = function(source){
|
||||
if(source in IMAGES){
|
||||
var img = IMAGES[source]
|
||||
var source = normalizePath(img.path)
|
||||
}
|
||||
var getter = $.Deferred()
|
||||
var cmd = 'vips im_header_string exif-ifd0-Orientation "$IN"'
|
||||
.replace(/\$IN/g, source.replace(fp, ''))
|
||||
proc.exec(cmd, function(error, stdout, stderr){
|
||||
getter.resolve(orientationExif2ImageGrid(parseInt(stdout.trim())))
|
||||
})
|
||||
return getter
|
||||
}
|
||||
|
||||
// preview generation...
|
||||
//
|
||||
// possible modes:
|
||||
@ -147,10 +195,9 @@ if(window.CEF_dumpJSON != null){
|
||||
// NOTE: rscale should be used for exactly tuned preview sizes...
|
||||
// NOTE: this will add already existing previews to IMAGES[gid]...
|
||||
//
|
||||
// XXX get image size without loading the image...
|
||||
// XXX make this not just vips-specific...
|
||||
// XXX path handling is a mess...
|
||||
window.makeImagePreviews = function(gid, sizes, mode){
|
||||
window.makeImagePreviews = function(gid, sizes, mode, no_update_loaded){
|
||||
mode = mode == null ? 'optimized' : mode
|
||||
|
||||
var img = IMAGES[gid]
|
||||
@ -172,26 +219,7 @@ if(window.CEF_dumpJSON != null){
|
||||
cache_path = cache_path.replace(fp, '')
|
||||
|
||||
// get cur image size...
|
||||
var size_getter = $.Deferred()
|
||||
|
||||
var width_getter = $.Deferred()
|
||||
var cmd = 'vips im_header_int width "$IN"'
|
||||
.replace(/\$IN/g, source.replace(fp, ''))
|
||||
proc.exec(cmd, function(error, stdout, stderr){
|
||||
width_getter.resolve(parseInt(stdout.trim()))
|
||||
})
|
||||
var height_getter = $.Deferred()
|
||||
var cmd = 'vips im_header_int height "$IN"'
|
||||
.replace(/\$IN/g, source.replace(fp, ''))
|
||||
proc.exec(cmd, function(error, stdout, stderr){
|
||||
height_getter.resolve(parseInt(stdout.trim()))
|
||||
})
|
||||
|
||||
$.when(width_getter, height_getter)
|
||||
.done(function(w, h){
|
||||
size_getter.resolve(Math.max(w, h))
|
||||
})
|
||||
|
||||
var size_getter = _getImageSize('max', source)
|
||||
|
||||
for(var i=0; i < sizes.length; i++){
|
||||
var size = sizes[i]
|
||||
@ -207,7 +235,7 @@ if(window.CEF_dumpJSON != null){
|
||||
// }(...))
|
||||
// produces a "undefined is not a function" in part of the
|
||||
// invocations, usually the later ones...
|
||||
var _f = function(size, target_path, deferred){
|
||||
[function(size, target_path, deferred){
|
||||
// wait for current image size if needed...
|
||||
size_getter.done(function(source_size){
|
||||
|
||||
@ -255,8 +283,8 @@ if(window.CEF_dumpJSON != null){
|
||||
|
||||
// XXX make this compatible with other image processors...
|
||||
var cmd = 'vips im_shrink "$IN:$RSCALE" "$OUT:$COMPRESSION" $FACTOR $FACTOR'
|
||||
.replace(/\$RSCALE/g, rscale)
|
||||
.replace(/\$IN/g, source.replace(fp, ''))
|
||||
.replace(/\$RSCALE/g, rscale)
|
||||
.replace(/\$OUT/g, preview_path)
|
||||
.replace(/\$COMPRESSION/g, compression)
|
||||
.replace(/\$FACTOR/g, factor)
|
||||
@ -288,16 +316,38 @@ if(window.CEF_dumpJSON != null){
|
||||
})
|
||||
})
|
||||
})
|
||||
}
|
||||
// NOTE: wrapping this in a closure saves the specific data that would
|
||||
// otherwise be overwritten by the next loop iteration...
|
||||
_f(size, target_path, deferred)
|
||||
}(size, target_path, deferred)]
|
||||
}
|
||||
|
||||
return $.when.apply(null, previews)
|
||||
var res = $.when.apply(null, previews)
|
||||
|
||||
// update loaded images...
|
||||
if(!no_update_loaded){
|
||||
res.done(function(){
|
||||
var o = getImage(gid)
|
||||
if(o.length > 0){
|
||||
updateImage(o)
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
return res
|
||||
}
|
||||
|
||||
// XXX needs more testing...
|
||||
// - for some reason this is a bit slower than the queued version
|
||||
// ...in spite of being managed by node.js
|
||||
// - will this be faster on SMP/multi-core?
|
||||
window.makeImagesPreviews = function(gids, sizes, mode){
|
||||
gids = gids == null ? getClosestGIDs() : gids
|
||||
return $.when.apply(null, gids.map(function(gid){
|
||||
return makeImagePreviews(gid, sizes, mode)
|
||||
}))
|
||||
}
|
||||
|
||||
window._PREVIW_CREATE_QUEUE = null
|
||||
// Queued version of makeImagesPreviews(...)
|
||||
//
|
||||
// XXX is this robust enough???
|
||||
// of one deferred hangs or breaks without finalizing this will
|
||||
// stall the whole queue...
|
||||
@ -308,7 +358,8 @@ if(window.CEF_dumpJSON != null){
|
||||
// NOTE: this will remove the old deferred if it us resolved, thus
|
||||
// clearing the "log" of previous operations, unless keep_log
|
||||
// is set to true...
|
||||
window.makeImagesPreviewsQ = function(gids, keep_log, mode){
|
||||
window.makeImagesPreviewsQ = function(gids, sizes, mode, keep_log){
|
||||
gids = gids == null ? getClosestGIDs() : gids
|
||||
var previews = []
|
||||
|
||||
$.each(gids, function(i, e){
|
||||
@ -329,7 +380,7 @@ if(window.CEF_dumpJSON != null){
|
||||
|
||||
// append to deffered queue...
|
||||
last.always(function(){
|
||||
makeImagePreviews(e, null, mode)
|
||||
makeImagePreviews(e, sizes, mode)
|
||||
.progress(function(state){
|
||||
deferred.notify(state)
|
||||
})
|
||||
|
||||
44
ui/data.js
44
ui/data.js
@ -191,7 +191,7 @@ function makeImageGIDDistanceCmp(gid, get, order){
|
||||
}
|
||||
|
||||
|
||||
// NOTE: essentially this is a 2D distance compatison from gid...
|
||||
// NOTE: essentially this is a 2D distance comparison from gid...
|
||||
//
|
||||
// XXX make this faster...
|
||||
// XXX this is fun, but do we actually need this?
|
||||
@ -402,6 +402,35 @@ Array.prototype.binSearch = function(target, cmp, get){
|
||||
}
|
||||
|
||||
|
||||
// Orientation transaltion...
|
||||
function orientationExif2ImageGrid(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]
|
||||
}
|
||||
}
|
||||
|
||||
|
||||
// Base URL interface...
|
||||
//
|
||||
// NOTE: changing a base URL will trigger a baseURLChanged event...
|
||||
@ -410,6 +439,7 @@ function setBaseURL(url){
|
||||
url = url.replace(/\/*$/, '/')
|
||||
BASE_URL = url
|
||||
$('.viewer').trigger('baseURLChanged', [old_url, url])
|
||||
return url
|
||||
}
|
||||
function getBaseURL(){
|
||||
return BASE_URL
|
||||
@ -600,6 +630,16 @@ function updateRibbonOrder(no_reload_viewer){
|
||||
}
|
||||
|
||||
|
||||
// get list of gids sorted by proximity to current gid
|
||||
//
|
||||
// NOTE: the distance used is the actual 2D distance...
|
||||
function getClosestGIDs(gid){
|
||||
gid = gid == null ? getImageGID() : gid
|
||||
//return DATA.order.slice().sort(makeImageGIDDistanceCmp(gid))
|
||||
return DATA.order.slice().sort(makeImageRibbonDistanceCmp(gid))
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* Constructors
|
||||
@ -608,6 +648,8 @@ function updateRibbonOrder(no_reload_viewer){
|
||||
// Construct an IMAGES object from list of urls.
|
||||
//
|
||||
// NOTE: this depends on that the base dir contains ALL the images...
|
||||
// NOTE: if base is not given, this will not read image to get
|
||||
// orientation data...
|
||||
function imagesFromUrls(lst){
|
||||
var res = {}
|
||||
|
||||
|
||||
63
ui/files.js
63
ui/files.js
@ -634,5 +634,68 @@ function exportTo(path, im_name, dir_name, size){
|
||||
|
||||
|
||||
|
||||
/*********************************************************************/
|
||||
|
||||
// XXX this depends on getImageOrientation(...)
|
||||
function updateImageOrientation(gid, no_update_loaded){
|
||||
gid = gid == null ? getImageGID() : gid
|
||||
var img = IMAGES[gid]
|
||||
|
||||
return getImageOrientation(normalizePath(img.path))
|
||||
.done(function(o){
|
||||
img.orientation = o.orientation
|
||||
img.flipped = o.flipped
|
||||
|
||||
// update loaded images...
|
||||
if(!no_update_loaded){
|
||||
var o = getImage(gid)
|
||||
if(o.length > 0){
|
||||
updateImage(o)
|
||||
}
|
||||
}
|
||||
})
|
||||
}
|
||||
|
||||
|
||||
function updateImagesOrientation(gids, no_update_loaded){
|
||||
gids = gids == null ? getClosestGIDs() : gids
|
||||
var res = []
|
||||
|
||||
$.each(gids, function(_, gid){
|
||||
res.push(updateImageOrientation(gid, no_update_loaded))
|
||||
})
|
||||
|
||||
return $.when.apply(null, res)
|
||||
}
|
||||
|
||||
|
||||
// queued version of updateImagesOrientation(...)
|
||||
function updateImagesOrientationQ(gids, no_update_loaded){
|
||||
gids = gids == null ? getClosestGIDs() : gids
|
||||
var res = []
|
||||
|
||||
if(window.getImageOrientation == null){
|
||||
return
|
||||
}
|
||||
|
||||
var last = $.Deferred().resolve()
|
||||
|
||||
$.each(gids, function(_, gid){
|
||||
var cur = $.Deferred()
|
||||
last.done(function(){
|
||||
last = updateImageOrientation(gid, no_update_loaded)
|
||||
.done(function(o){
|
||||
cur.resolve()
|
||||
})
|
||||
})
|
||||
|
||||
res.push(cur)
|
||||
})
|
||||
|
||||
return $.when.apply(null, res)
|
||||
}
|
||||
|
||||
|
||||
|
||||
/**********************************************************************
|
||||
* vim:set ts=4 sw=4 : */
|
||||
|
||||
Loading…
x
Reference in New Issue
Block a user