mirror of
				https://github.com/flynx/ImageGrid.git
				synced 2025-10-31 11:20:09 +00:00 
			
		
		
		
	added bulk data tags import/export from/to images + some plyfils...
Signed-off-by: Alex A. Naanou <alex.nanou@gmail.com>
This commit is contained in:
		
							parent
							
								
									555ac6ec85
								
							
						
					
					
						commit
						4e44480c1f
					
				| @ -231,7 +231,7 @@ var DataPrototype = { | ||||
| 		} | ||||
| 
 | ||||
| 		gids.forEach(function(e){ | ||||
| 			i = order.indexOf(e) | ||||
| 			var i = order.indexOf(e) | ||||
| 			if(i >= 0){ | ||||
| 				var o = target[i] | ||||
| 				// save overwritten target items if keep_target_items 
 | ||||
| @ -2284,6 +2284,154 @@ var DataWithTagsPrototype = { | ||||
| 	// 		....is there a way not to say DataPrototype here???
 | ||||
| 	__gid_lists: DataPrototype.__gid_lists.concat(['tags']), | ||||
| 
 | ||||
| 
 | ||||
| 	// Load tags from images...
 | ||||
| 	//
 | ||||
| 	// 	Merge image tags to data...
 | ||||
| 	// 	.tagsFromImages(images)
 | ||||
| 	// 		-> data
 | ||||
| 	//
 | ||||
| 	// 	Load image tags to data dropping any changes in data...
 | ||||
| 	// 	.tagsFromImages(images, 'reset')
 | ||||
| 	// 		-> data
 | ||||
| 	//
 | ||||
| 	// XXX should this be here???
 | ||||
| 	// XXX this depend on image structure...
 | ||||
| 	tagsFromImages: function(images, mode){ | ||||
| 		if(mode == 'reset'){ | ||||
| 			this.tags = {} | ||||
| 		} | ||||
| 		for(var gid in images){ | ||||
| 			var img = images[gid] | ||||
| 			if(img.tags != null){ | ||||
| 				this.tag(img.tags, gid) | ||||
| 			} | ||||
| 		} | ||||
| 		return this | ||||
| 			.sortTags() | ||||
| 	}, | ||||
| 
 | ||||
| 	// Transfer tags to images...
 | ||||
| 	//
 | ||||
| 	// 	Merge data tags to images...
 | ||||
| 	// 	.tagsToImages(images)
 | ||||
| 	// 	.tagsToImages(images, true)
 | ||||
| 	// 	.tagsToImages(images, 'merge')
 | ||||
| 	// 		-> data
 | ||||
| 	//
 | ||||
| 	// 	Merge data tags to images without buffering...
 | ||||
| 	// 	.tagsToImages(images, 'unbuffered')
 | ||||
| 	// 		-> data
 | ||||
| 	//
 | ||||
| 	// 	Reset image tags from data...
 | ||||
| 	// 	.tagsToImages(images, 'rest')
 | ||||
| 	// 		-> data
 | ||||
| 	//
 | ||||
| 	// XXX should this be here???
 | ||||
| 	// XXX this depend on image structure...
 | ||||
| 	// XXX should this use image API for creating images???
 | ||||
| 	tagsToImages: function(images, mode, updated){ | ||||
| 		mode = mode || 'merge' | ||||
| 		updated = updated || [] | ||||
| 
 | ||||
| 		// mark gid as updated...
 | ||||
| 		var _updated = function(gid){ | ||||
| 			if(updated != null && updated.indexOf(gid) < 0){ | ||||
| 				updated.push(gid) | ||||
| 			} | ||||
| 		} | ||||
| 		// get or create an image with tags...
 | ||||
| 		// XXX should this use image API for creating???
 | ||||
| 		var _get = function(images, gid){ | ||||
| 			var img = images[gid] | ||||
| 			// create a new image...
 | ||||
| 			if(img == null){ | ||||
| 				img = images[gid] = {} | ||||
| 				_updated(gid) | ||||
| 			} | ||||
| 
 | ||||
| 			var tags = img.tags | ||||
| 			// no prior tags...
 | ||||
| 			if(tags == null){ | ||||
| 				tags = img.tags = [] | ||||
| 				_updated(gid) | ||||
| 			} | ||||
| 
 | ||||
| 			return img | ||||
| 		} | ||||
| 
 | ||||
| 		// buffered mode...
 | ||||
| 		// 	- uses more memory
 | ||||
| 		// 	+ one write mer image
 | ||||
| 		if(mode != 'unbuffered'){ | ||||
| 			// build the buffer...
 | ||||
| 			var buffer = {} | ||||
| 			this.tagsToImages(buffer, 'unbuffered') | ||||
| 
 | ||||
| 			// reset mode...
 | ||||
| 			if(mode == 'reset'){ | ||||
| 				// iterate through all the gids (both images and buffer/data)
 | ||||
| 				for(var gid in Object.keys(images) | ||||
| 									.concat(Object.keys(buffer)) | ||||
| 									.unique()){ | ||||
| 					// no tags / remove...
 | ||||
| 					if(buffer[gid] == null || buffer[gid].tags.length == 0){ | ||||
| 						// the image exists and has tags...
 | ||||
| 						if(images[gid] != null && images[gid].tags != null){ | ||||
| 							delete images[gid].tags | ||||
| 							_updated(gid) | ||||
| 						} | ||||
| 
 | ||||
| 					// tags / set...
 | ||||
| 					} else { | ||||
| 						var img = _get(images, gid) | ||||
| 						var before = img.tags.slice() | ||||
| 
 | ||||
| 						img.tags = buffer[gid].tags | ||||
| 
 | ||||
| 						// check if we actually changed anything...
 | ||||
| 						if(!before.setCmp(img.tags)){ | ||||
| 							_updated(gid) | ||||
| 						} | ||||
| 					} | ||||
| 				} | ||||
| 
 | ||||
| 			// merge mode...
 | ||||
| 			} else { | ||||
| 				for(var gid in buffer){ | ||||
| 					var img = _get(images, gid) | ||||
| 					var l = img.tags.length | ||||
| 					img.tags = img.tags.concat(buffer[gid].tags).unique() | ||||
| 					// we are updated iff length changed...
 | ||||
| 					// NOTE: this is true as we are not removing anything 
 | ||||
| 					// 		thus the length can only increase if changes are
 | ||||
| 					// 		made...
 | ||||
| 					if(l != img.tags.length){ | ||||
| 						_updated(gid) | ||||
| 					} | ||||
| 				} | ||||
| 			} | ||||
| 
 | ||||
| 		// unbuffered (brain-dead) mode...
 | ||||
| 		// 	+ no extra memory
 | ||||
| 		// 	- multiple writes per image (one per tag)
 | ||||
| 		} else { | ||||
| 			var tagset = this.tags | ||||
| 			for(var tag in tagset){ | ||||
| 				tagset[tag].forEach(function(gid){ | ||||
| 					var img = _get(images, gid) | ||||
| 
 | ||||
| 					if(img.tags.indexOf(tag) < 0){ | ||||
| 						img.tags.push(tag) | ||||
| 						_updated(gid) | ||||
| 					} | ||||
| 				}) | ||||
| 			} | ||||
| 		} | ||||
| 		return this | ||||
| 	}, | ||||
| 
 | ||||
| 
 | ||||
| 	// NOTE: this is here only to make the tags mutable...
 | ||||
| 	crop: function(){ | ||||
| 		var crop = DataWithTagsPrototype.__proto__.crop.apply(this, arguments) | ||||
|  | ||||
| @ -222,7 +222,8 @@ module.FeatureSet = { | ||||
| 		var l = lst.length | ||||
| 		lst = lst | ||||
| 			// remove duplicates, keeping only the first occurance...
 | ||||
| 			.filter(function(e, i, l){ return l.indexOf(e) == i }) | ||||
| 			//.filter(function(e, i, l){ return l.indexOf(e) == i })
 | ||||
| 			.unique() | ||||
| 			// remove undefined features...
 | ||||
| 			.filter(function(e){ return that[e] != null }) | ||||
| 			// build the sort table: [ <priority>, <rev-index>, <elem> ]
 | ||||
|  | ||||
| @ -1335,6 +1335,40 @@ Array.prototype.compact = function(){ | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // return an array with duplicate elements removed...
 | ||||
| //
 | ||||
| Array.prototype.unique = function(){ | ||||
| 	return this.filter(function(e, i, a){ return a.indexOf(e) == i }) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| // Compare two arrays...
 | ||||
| //
 | ||||
| Array.prototype.cmp = function(other){ | ||||
| 	if(this === other){ | ||||
| 		return true | ||||
| 	} | ||||
| 	if(this.length != other.length){ | ||||
| 		return false | ||||
| 	} | ||||
| 	for(var i=0; i<this.length; i++){ | ||||
| 		if(this[i] != other[i]){ | ||||
| 			return false | ||||
| 		} | ||||
| 	} | ||||
| 	return true | ||||
| } | ||||
| 
 | ||||
| // Compare two Arrays as sets...
 | ||||
| //
 | ||||
| // This will ignore order
 | ||||
| Array.prototype.setCmp = function(other){ | ||||
| 	return this === other  | ||||
| 		|| this.unique().sort().cmp(other.unique().sort()) | ||||
| } | ||||
| 
 | ||||
| 
 | ||||
| 
 | ||||
| // like .length but for sparse arrays will return the element count...
 | ||||
| // XXX make this a prop...
 | ||||
| /* | ||||
|  | ||||
		Loading…
	
	
			
			x
			
			
		
	
		Reference in New Issue
	
	Block a user