Added more functionality for image tagging (tag reregistered, tag deleted registered, tag all and overwrite), AND added the '_tagged' prefix

master
Jonathan Chan 2 years ago
parent 8dbeca747c
commit c6138c5a19

@ -107,18 +107,19 @@ function batch_register_images(batchIndex, site_path, site_name, images_to_regis
}
function imagesNotRegistered(site_images_all, photoshop_images) {
function imagesNotRegistered(processed_images, photoshop_images) {
var site_images = [];
var processed_images_to_register = [];
// Extract images that haven't been registered
for (var i = 0; i < site_images_all.length; i ++) { // For each site image
for (var i = 0; i < processed_images.length; i ++) { // For each site image
var isRegistered = false;
for (var j = 0; j < photoshop_images.length; j++ ) { // Check if already exists in photoshop images
//var site_name_CHECK = site_images_all[i].name.slice(0,-4) + '_CHECK.jpg';
var site_image = site_images_all[i].name.toString()
var processed_tagged = processed_images[i].name.slice(0,-4) + '_tagged.jpg';
processed_tagged = processed_tagged.replace("%20", "_")
var site_image = processed_images[i].name.toString()
site_image = site_image.replace("%20", "_")
if((site_image == photoshop_images[j].name.toString())) {
if((site_image == photoshop_images[j].name.toString()) || (processed_tagged == photoshop_images[j].name.toString())) {
isRegistered = true;
break;
}
@ -128,10 +129,10 @@ function imagesNotRegistered(site_images_all, photoshop_images) {
//var s = site2add.replace("%20", "_") // getFiles() reads in white space as "%20". So convert to "_"
//alert(s)
//var s = File(site_image);
site_images.push(site_images_all[i]);
processed_images_to_register.push(processed_images[i]);
}
}
return site_images
return processed_images_to_register
}
function stackFiles(sFiles){

@ -1,342 +0,0 @@
// SCRIPT LOGIC
// for site in sites:
// for year in years:
// register_images()
// VARIABLE DEFINITIONS
// images_to_register = All images to be registered for a given site and year (no target or seed)
// batch_images_to_register = Batch images to be registered (no target or seed)
// batch_images_all = Target, seed and batch images to be registered
var site_name = "cooya" // ADD SITE NAME HERE
var batch_size = 15;
var parent_dir = File($.fileName).parent.parent.fsName;
var batch_download_csv = File(parent_dir + "/coastsnap_sites.csv")
// retreive site names from batch_download.csv
var csv_data=[];
batch_download_csv.open('r');
while(!batch_download_csv.eof){
var InputLine = batch_download_csv.readln();
if(InputLine.length > 3) csv_data.push(InputLine);
}
batch_download_csv.close();
var site_names = csv_data.toString().split(",")
// Retrieve images parent directory from CoastSnap_Sites.csv
var parent_folder_path = File(site_names[9]);
var batch_images_to_register = []; // Used in exportLayersToPNG
var site_path = parent_folder_path + "/Images/" + site_name;
// Retrieve target and seed images for the site
var target_folder = new Folder(site_path + '/Target Image');
var seed_folder = new Folder(site_path + '/Target Image' + '/Seed Images');
var target_image = target_folder.getFiles("Target.jpg");
var seed_images = seed_folder.getFiles("*.jpg");
// Retrieve processed image years for the site
var processed_folder = new Folder(site_path + '/Processed');
var processed_subFolders = processed_folder.getFiles()
// Loop through years
for (var j = 0; j < processed_subFolders.length; j++) {
var year = processed_subFolders[j].name.toString();
var processed_folder = new Folder(site_path + '/Processed/' + year);
var photoshop_folder = new Folder(site_path + '/Photoshop/' + year);
var processed_images_all = processed_folder.getFiles("*.jpg");
var photoshop_images = photoshop_folder.getFiles("*.jpg");
// Ignore images in processed that have already been registered
var images_to_register = imagesNotRegistered(processed_images_all, photoshop_images);
// Register images in batches, to avoid reaching the image limit that causes photoshop to crash
for (var k = 0; k < images_to_register.length; k += batch_size) {
batch_register_images(k, site_path, site_name, images_to_register, target_image, seed_images);
}
}
// This is the main function, responsible for calling photoshop functions
// in a sequential order to register all_images
function batch_register_images(batchIndex, site_path, site_name, images_to_register, target_image, seed_images) {
var batch_images_all = [];
batch_images_to_register = [];
batch_images_all.push(target_image[0])
for (var i = 0; i < seed_images.length; i++ ) {
batch_images_all.push(seed_images[i]);
}
for (var i = batchIndex*1; i < batchIndex + batch_size; i++) {
if(i < images_to_register.length) {
batch_images_all.push(images_to_register[i]);
batch_images_to_register.push(images_to_register[i].name);
}
}
stackFiles(batch_images_all);
resizeLayers();
lockTarget();
selectAllLayers();
autoAlign();
var target_size = cropToTarget();
var target_width = target_size[0];
var target_height = target_size[1];
savePhotoshopDocument(site_path, site_name);
exportLayersToPNG(target_width, target_height, batch_images_to_register, seed_images); // Won't overwrite images that already exist
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES)
}
function imagesNotRegistered(site_images_all, photoshop_images) {
var site_images = [];
// Extract images that haven't been registered
for (var i = 0; i < site_images_all.length; i ++) { // For each site image
var isRegistered = false;
for (var j = 0; j < photoshop_images.length; j++ ) { // Check if already exists in photoshop images
var site_name_CHECK = site_images_all[i].name.slice(0,-4) + '_CHECK.jpg';
if((site_images_all[i].name.toString() == photoshop_images[j].name.toString()) || (site_name_CHECK.toString() == photoshop_images[j].name.toString())) {
isRegistered = true;
break;
}
}
if(!isRegistered) { // If it doesn't, register it
site_images.push(site_images_all[i]);
}
}
return site_images
}
function stackFiles(sFiles){
var loadLayersFromScript = true;
var SCRIPTS_FOLDER = decodeURI(app.path + '/' + localize('$$$/ScriptingSupport/InstalledScripts=Presets/Scripts'));
$.evalFile( new File(SCRIPTS_FOLDER + '/Load Files into Stack.jsx'));
loadLayers.intoStack(sFiles, false);
};
function resizeLayers() {
var doc = app.activeDocument;
var targetImage = app.activeDocument.artLayers.getByName("Target.jpg")
// Retrieve Target image dimensions
var target_bounds = targetImage.bounds;
var target_width = target_bounds[2] - target_bounds[0];
var target_height = target_bounds[3] - target_bounds[1];
// Update Target Image dimensions
var new_width = 1280;
preferences.rulerUnits = Units.PIXELS;
var s = (new_width/target_width)*100;
targetImage.resize(s, s, AnchorPosition.TOPLEFT)
// Retrieve new Target image dimensions
var target_bounds = targetImage.bounds;
var target_width = target_bounds[2] - target_bounds[0];
var target_height = target_bounds[3] - target_bounds[1];
// Make layers similar dimensions to new Target
var layerName = doc.layers;
for (var ii = 0; ii < layerName.length; ii++) { //looping through all the layers
var current_layer = layerName[ii];
preferences.rulerUnits = Units.PIXELS;
var b = current_layer.bounds;
var layer_width = b[2]-b[0];
var layer_height = b[3]-b[1];
if (layer_height >= layer_width) {
var s = (target_height/layer_height)*100;
}
else {
var s = (target_width/layer_width)*100;
}
current_layer.resize(s, s, AnchorPosition.TOPLEFT)
}
}
function selectAllLayers() {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
desc.putReference( charIDToTypeID('null'), ref );
executeAction( stringIDToTypeID('selectAllLayers'), desc, DialogModes.NO );
};
function autoAlign() {
var desc = new ActionDescriptor();
var ref = new ActionReference();
ref.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
desc.putReference( charIDToTypeID('null'), ref );
desc.putEnumerated( charIDToTypeID('Usng'), charIDToTypeID('ADSt'), stringIDToTypeID('ADSContent') );
desc.putEnumerated( charIDToTypeID('Aply'), stringIDToTypeID('projection'), charIDToTypeID('Auto') );
desc.putBoolean( stringIDToTypeID('vignette'), false );
desc.putBoolean( stringIDToTypeID('radialDistort'), false );
executeAction( charIDToTypeID('Algn'), desc, DialogModes.NO );
};
function lockTarget() {
var layerRef = app.activeDocument.artLayers.getByName("Target.jpg")
layerRef.allLocked = true;
app.activeDocument.activeLayer.linkedLayers
}
// CROP
function cropToTarget() {
var layerRef = app.activeDocument.artLayers.getByName("Target.jpg")
app.activeDocument.crop(layerRef.bounds)
var theBounds = app.activeDocument.activeLayer.bounds;
var layerWidth = theBounds[2] - theBounds[0];
var layerHeight = theBounds[3] - theBounds[1];
return [layerWidth, layerHeight];
}
// TO BE IMPLEMENTED
// function imageSize(layerRef) {
// }
// SAVE PHOTOSHOP DOCUMENT
function savePhotoshopDocument(site_path, site_name) {
var PSdocumentFile = new File(site_path + '/' + site_name + '.psd');
app.activeDocument.saveAs(PSdocumentFile)
}
// EXPORT LAYERS TO IMAGES
// $.evalFile(File(app.path + '/Presets/Scripts/Export Layers To Files.jsx'));
function exportLayersToPNG(target_width, target_height, batch_images_to_register, seed_images){
if(!documents.length) return;
var doc = activeDocument;
var oldPath = activeDocument.path;
var outFolder = new Folder(oldPath + "/Photoshop/" + year);
if (!outFolder.exists) {
outFolder.create();
}
scanLayerSets(doc);
function scanLayerSets(el) {
// // find layer groups
// for(var a=0;a<el.layerSets.length;a++){
// var lname = el.layerSets[a].name;
// if (lname.substr(-4) == ".jpg") {
// saveLayer(el.layers.getByName(lname), lname, oldPath, true);
// } else {
// // recursive
// scanLayerSets(el.layerSets[a]);
// }
// }
var layerToRegister = true;
// find plain layers in current group that are site images only (not target or seed)
for(var j=0; j<el.artLayers.length; j++) { // Loop through photoshop document layers (images)
var name = el.artLayers[j].name;
layerToRegister = true;
// for (var i = 0; i < seed_images.length; i++ ) {
// if((seed_images[i].toString() == name.toString()) || (name.toString() == 'Target.jpg')) {
// layerToRegister = false;
// }
// }
// if(layerToRegister) {
// app.activeDocument.activeLayer = el.layers.getByName(name);
// var theBounds = app.activeDocument.activeLayer.bounds;
// var aligned_image_width = theBounds[2] - theBounds[0];
// var aligned_image_height = theBounds[3] - theBounds[1];
// var name_updated = name;
// // COMAPRE THE DIMENSIONS OF THE ALIGNED IMAGE WITH THE TARGET
// // IF SIGNIFICANT DIFFERENCE (30%), TAG IMAGE WITH '_CHECK.jpg'
// if((aligned_image_width/target_width) < 0.7 || (aligned_image_height/target_height) < 0.7) {
// name_updated = name.slice(0,-4) + '_CHECK.jpg';
// }
// saveLayer(el.layers.getByName(name), name_updated, oldPath, false);
// }
for (var i = 0; i < batch_images_to_register.length; i++ ) { // Loop through batch_images_to_register
if(batch_images_to_register[i].toString() == name.toString()) {
app.activeDocument.activeLayer = el.layers.getByName(name);
var theBounds = app.activeDocument.activeLayer.bounds;
var aligned_image_width = theBounds[2] - theBounds[0];
var aligned_image_height = theBounds[3] - theBounds[1];
var name_updated = name;
// COMAPRE THE DIMENSIONS OF THE ALIGNED IMAGE WITH THE TARGET
// IF SIGNIFICANT DIFFERENCE (30%), TAG IMAGE WITH '_CHECK.jpg'
// if((aligned_image_width/target_width) < 0.7 || (aligned_image_height/target_height) < 0.7) {
// name_updated = name.slice(0,-4) + '_CHECK.jpg';
// }
saveLayer(el.layers.getByName(name), name_updated, oldPath, false);
}
}
}
}
function saveLayer(layer, lname, path, shouldMerge) {
activeDocument.activeLayer = layer;
dupLayers();
if (shouldMerge === undefined || shouldMerge === true) {
activeDocument.mergeVisibleLayers();
}
//activeDocument.trim(TrimType.TRANSPARENT,true,true,true,true);
var saveFile = File(path +"/Photoshop/"+year+"/"+lname);
SavePNG(saveFile);
app.activeDocument.close(SaveOptions.DONOTSAVECHANGES);
}
};
function dupLayers() {
var desc143 = new ActionDescriptor();
var ref73 = new ActionReference();
ref73.putClass( charIDToTypeID('Dcmn') );
desc143.putReference( charIDToTypeID('null'), ref73 );
desc143.putString( charIDToTypeID('Nm '), activeDocument.activeLayer.name );
var ref74 = new ActionReference();
ref74.putEnumerated( charIDToTypeID('Lyr '), charIDToTypeID('Ordn'), charIDToTypeID('Trgt') );
desc143.putReference( charIDToTypeID('Usng'), ref74 );
executeAction( charIDToTypeID('Mk '), desc143, DialogModes.NO );
};
function SavePNG(saveFile){
var pngOpts = new ExportOptionsSaveForWeb;
pngOpts.format = SaveDocumentType.JPEG;
pngOpts.PNG8 = false;
pngOpts.transparency = true;
pngOpts.interlaced = false;
pngOpts.quality = 100;
activeDocument.exportDocument(new File(saveFile),ExportType.SAVEFORWEB,pngOpts);
}

@ -25,7 +25,8 @@ For each site in Images Parent Directory:
# Get command-line arguments
parser = argparse.ArgumentParser()
parser.add_argument("--tag_deleted", action='store_true', required=False)
parser.add_argument("--tag_reregistered", action='store_true', required=False)
parser.add_argument("--tag_registered_deleted", action='store_true', required=False)
parser.add_argument("--overwrite", action='store_true', required=False)
parser.add_argument("--site", type=str, required=False)
args = parser.parse_args()
@ -59,12 +60,79 @@ def tag_image(image2tag):
# Tag image with text
draw.text((20, rect_height/4),image2tag.tag, font = image2tag.font, fill=(0, 0, 0))
registered_path_wrong = image2tag.pathname[:-4] + '_registered.jpg'
registered_path = registered_path_wrong.replace('Photoshop', 'Registered')
#registered_path_wrong = image2tag.pathname[:-4] + '_registered.jpg'
#registered_path = registered_path_wrong.replace('Photoshop', 'Registered')
image = image.convert('RGB')
image.save(registered_path)
#image.save(registered_path)
image.save(image2tag.registered_pathname)
#-----------------------------------------------------------------------------#
# Loop Photoshop directory and print reregistered images
def loop_reregistered(site, tag, reregister_all):
i = 1
num_2_tag = 0
tides_df = False
print("\nSite: " + site)
photoshop_path = images_dir +'/'+ site + '/Photoshop'
try: # Check if site contains 'Processed' directory
years_list = os.listdir(photoshop_path)
years_list.reverse()
except: # Site doesn't contain 'Processed'. Go to next site.
return
# Loop through YEARS
for year in years_list:
if not year.isdigit() and len(year) != 4: # Check folder name is in the format "YYYY"
continue
year_path = photoshop_path + '/' + year
image_list = os.listdir(year_path)
image_list.reverse()
# Loop through IMAGES in photoshop
for image_filename in image_list:
image_filename_no_suffix = image_filename.replace("_tagged","");
reregistered_image_path = year_path + '/' + image_filename_no_suffix
if os.path.isfile(year_path + '/' + image_filename_no_suffix):
if not tag:
print(image_filename)
num_2_tag += 1
else:
registered_year_path = year_path.replace('Photoshop', 'Registered')
registered_image_path = registered_year_path + '/' + image_filename_no_suffix[:-4] + '_registered.jpg'
if args.tag_reregistered and ("_tagged" not in image_filename) and not reregister_all:
action = input(image_filename +": ")
if action == 'y':
print("Tagging image\n")
pass
else:
print("Skip\n")
continue
# Case: Image not tagged, 'overwrite' = True or 'tag reregistered' = True
if not os.path.exists(registered_year_path): # Chech that registered/year directory exists
os.makedirs(registered_year_path) # if not, create it
pathname = os.path.join(year_path, image_filename)
image2tag = RegisteredImage(pathname, image_filename, registered_image_path) # Create image object
if i == 1: # Retrieve Tide Data once for each site
tides_df = get_site_tide_data(images_parent_dir, site)
if isinstance(tides_df, pd.DataFrame): image2tag.get_tide(tides_df)
image2tag.get_font()
image2tag.get_dimensions()
image2tag.create_tag()
tag_image(image2tag)
i += 1
# Add '_tagged' suffix to image in Photoshop
new_pathname = pathname[:-4] + '_tagged.jpg'
os.rename(pathname, new_pathname)
return num_2_tag
#-----------------------------------------------------------------------------#
# Main function (called below)
@ -84,25 +152,29 @@ def main(site):
# Loop through YEARS
for year in years_list:
if not year.isdigit() and len(year) != 4: # Check folder name is in the format "YYYY"
continue
if site_complete: break
year_path = photoshop_path + '/' + year
image_list = os.listdir(year_path)
image_list.reverse()
# Loop through IMAGES
# Loop through IMAGES in photoshop
for image_filename in image_list:
registered_year_path = year_path.replace('Photoshop', 'Registered')
registered_image_path = registered_year_path + '/' + image_filename[:-4] + '_registered.jpg'
image_filename_no_suffix = image_filename.replace("_tagged","");
registered_image_path = registered_year_path + '/' + image_filename_no_suffix[:-4] + '_registered.jpg'
if site not in image_filename: # Check the filename has the site in it
continue
# Case: Image already tagged
# Case: Image tagged and in 'Registered'
if os.path.isfile(registered_image_path):
if args.tag_deleted: # If 'tag_deleted' = True, continue to next image
if args.tag_registered_deleted: # If 'tag_registered_deleted' = True, continue to next image
continue
elif args.overwrite: # If 'overwrite' = True, pass and tag image
elif args.overwrite: # If 'overwrite' = True, pass and tag image
pass
else: # Otherwise, stop tagging and go to the next site
else: # Stop tagging and go to the next site
site_complete = True;
if i == 0:
print(site + ": " + str(i) + " images tagged")
@ -111,23 +183,30 @@ def main(site):
else:
print(site + ": " + str(i) + " images tagged no tide")
return
# Case: Image not tagged or 'overwrite' = True
# Case: Image not tagged, 'overwrite' = True or 'tag reregistered' = True
if not os.path.exists(registered_year_path): # Chech that registered/year directory exists
os.makedirs(registered_year_path) # if not, create it
i += 1
pathname = os.path.join(year_path, image_filename)
image2tag = RegisteredImage(pathname, image_filename) # Create image object
image2tag = RegisteredImage(pathname, image_filename, registered_image_path) # Create image object
if i == 1: # Retrieve Tide Data once for each site
tides_df = get_site_tide_data(images_parent_dir, site)
font = image2tag.get_font()
image2tag.get_font()
image2tag.get_dimensions()
if isinstance(tides_df, pd.DataFrame): image2tag.get_tide(tides_df)
image2tag.create_tag()
tag_image(image2tag)
# Add '_tagged' suffix if not already there
old_tagged_image_path = year_path + '/' + image_filename_no_suffix
new_tagged_image_path = year_path + '/' + image_filename_no_suffix[:-4] + '_tagged.jpg'
if os.path.isfile(old_tagged_image_path):
os.rename(old_tagged_image_path, new_tagged_image_path)
# Case: All images tagged
if not site_complete:
if i == 0:
@ -138,13 +217,66 @@ def main(site):
print(site + ": " + str(i) + " images tagged no tide")
#-----------------------------------------------------------------------------#
# Calling the main function with the two cases
# Case: Tag reregistered images
reregister_all = True
tag = False
count = 0
if args.tag_reregistered:
print("\n The following images have been reregistered:")
if args.site:
count = loop_reregistered(args.site, tag, reregister_all)
else:
for site in os.listdir(images_dir):
x = loop_reregistered(site, tag, reregister_all)
count = count + x
if count > 0:
reregister = input("\n\n Do you want to tag 'all' " + str(count) + " images or just 'some' of them: ")
print("\n")
tag = True
if reregister == 'all':
print("Tagging ALL reregistered images...")
elif reregister == 'some':
print(" Tagging SOME reregistered images. For each image:\n\n - to TAG, type the letter 'y' and hit enter \n - to SKIP, just hit enter\n")
reregister_all = False
else:
print(" User must type either 'all' or 'some' and then hit enter.")
exit()
if args.site: # Case 1: User specifies a site
loop_reregistered(args.site, tag, reregister_all)
else: # Case 2: No site specified. Tag all images
for site in os.listdir(images_dir):
loop_reregistered(site, tag, reregister_all)
#-----------------------------------------------------------------------------#
# Case: NOT reregistering images
else:
# Calling the main function with the two cases
if args.site: # Case 1: User specifies a site
main(args.site)
else: # Case 2: No site specified. Tag all images
for site in os.listdir(images_dir):
main(site)
if args.site: # Case 1: User specifies a site
main(args.site)
else: # Case 2: No site specified. Tag all images
for site in os.listdir(images_dir):
main(site)

@ -54,7 +54,7 @@ def progressbar(it, prefix="", size=60, out=sys.stdout): # Python3.3+
def get_site_tide_data(images_parent_dir, site):
print("Retrieving tide data")
# Retrieve tide data for the given site
db = openpyxl.load_workbook(images_parent_dir + "/Database/CoastSnapDB.xlsx")
beach_data = db[site]
@ -62,7 +62,7 @@ def get_site_tide_data(images_parent_dir, site):
if tide_filename == 'NO_TIDE.mat':
return False
tide_filename_pkl = tide_filename[:-4] + '.pkl'
tides_path = images_parent_dir + '/Tide Data/Tide_Data_Python/' + tide_filename_pkl
tides_df = pd.read_pickle(tides_path)
@ -71,9 +71,10 @@ def get_site_tide_data(images_parent_dir, site):
class RegisteredImage():
def __init__(self, pathname, filename):
def __init__(self, pathname, filename, registered_pathname):
self.pathname = pathname
self.filename = filename
self.registered_pathname = registered_pathname
filename_list = filename.split(".")
date = filename_list[3].split("_")
if 'snap' in filename_list:

Loading…
Cancel
Save