// Image Montage v.2 // January 26, 2014 // Developed by Lev Manovich, Matias Giachino, and Jay Chow / softwarestudies.com // this version: // 1) user defines width and height of the montage // 2) scales images vertically to the same size defined by the user - n_width (like in TiffViewer) // 3) uses the full width of every image (after scaling), aligning them next to each other // 4) error checking // 5) 3 levels of label // 6) color customization // input; either a folder full of images or a data file containing rows of filenames or filepaths // for the latter two options, the order of images in the file determines ther position in the montage (left to right, top to bottom) // if 1, opens gui to edit options in use_gui = 1; // if 0, takes files from a folder // if 1, takes files from a folder and its subfolders // if 2, takes files from a data file // if 3, takes files from a data file as full filepaths input_flag = 3; input_list = newArray("Folder", "Folder and Subfolders", "Data File", "Data File as Filepaths"); // if 0, make 8-bit grey scale montage // if 1, make RGB montage montage_RGB = 1; montage_RGB_list = newArray("Grayscale","RGB"); // sets the width of the montage canvas montage_width = 8000; // sets the height of the montage canvas montage_height = 8000; // the height to resize each image to height_row = 100; // sets the horizontal space between the images - in pixels h_interval = 10; // sets the vertical space between the images - in pixels v_interval = 10; // if 1, saves each frame of the montage process into a user-specified directory save_files_flag = 0; // the column from which to load the filename/filepath in a data file input_data_column = 0; cat_list_flag = 1; cat_list = newArray("None", "1 Level", "2 Level", "3 Level"); top_cat_data_column = 1; sec_cat_data_column = 2; third_cat_data_column = 3; // Background color var fill_bg_color = newArray(255,255,255); var text_color = newArray(110,110,110); // Category Text Config top_cat_text_size = 32; call("java.lang.System.gc"); // Open the GUI if option is active if(use_gui == 1){ Dialog.create("Image Montage"); Dialog.setInsets(0,0,0); Dialog.addMessage("Create a montage of images.\nImage sizes can vary."); Dialog.addMessage(" "); Dialog.setInsets(0,0,0); Dialog.addChoice("Image Source ", input_list, input_list[input_flag]); Dialog.addMessage(" "); Dialog.setInsets(0,0,0); Dialog.addMessage("Canvas"); Dialog.setInsets(0,0,0); Dialog.addChoice("Color Mode",montage_RGB_list,montage_RGB_list[montage_RGB]); Dialog.addNumber("Set Width ",montage_width,0,5,"px"); Dialog.addNumber("Set Height ",montage_height,0,5,"px"); Dialog.addMessage(" "); Dialog.setInsets(0,0,0); Dialog.addMessage("Images"); Dialog.addNumber("Row Height",height_row,0,5,"px"); Dialog.addNumber("X Spacing ",h_interval,0,5,"px"); Dialog.addNumber("Y Spacing ",v_interval,0,5,"px"); Dialog.addMessage(" "); Dialog.setInsets(0,0,0); Dialog.addChoice("Number of Labels", cat_list, cat_list[cat_list_flag]); Dialog.addMessage(" "); Dialog.setInsets(0,0,0); Dialog.addMessage("Labels"); Dialog.addNumber("Set Text Size",top_cat_text_size,0,5,"pt"); Dialog.addMessage(" "); Dialog.setInsets(0,0,0); Dialog.addMessage("Text Color"); Dialog.addSlider ("R", 0, 255, text_color[0]); Dialog.addSlider ("G", 0, 255, text_color[1]); Dialog.addSlider ("B", 0, 255, text_color[2]); Dialog.addMessage(" "); Dialog.setInsets(0,0,0); Dialog.addMessage("Background Color"); Dialog.addSlider ("R", 0, 255, fill_bg_color[0]); Dialog.addSlider ("G", 0, 255, fill_bg_color[1]); Dialog.addSlider ("B", 0, 255, fill_bg_color[2]); Dialog.addMessage(" "); Dialog.setInsets(0,0,0); Dialog.addMessage("Animation"); Dialog.setInsets(0,20,0); Dialog.addCheckbox("Save Images for Animation", save_files_flag); Dialog.show(); // Fetch choices input_flag_choice = Dialog.getChoice(); for(i=0; i montage_width) { // increment row row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; } open(path); id=getImageID; img_width = getWidth; img_height = getHeight; n_width = round((img_width * scaled_height)/img_height); run("Size...", "width=" + n_width + " height=" + scaled_height + " average interpolation=Bicubic"); // get image width and height after it was scaled n_width = getWidth; n_height = getHeight; start_x = total_x_width; start_y = row * (height_row + v_interval) + v_interval; run("Select All"); run("Copy"); selectImage(id_plot); makeRectangle(start_x, start_y, n_width, n_height); run("Paste"); selectImage(id); close(); // update display updateDisplay(); total_x_width = total_x_width + n_width + h_interval; if (save_files_flag == 1) { selectImage(id_plot); path_files = dir_anim + "frame_" + curImg; saveAs("PNG", path_files); print("image " + curImg + " saved"); } curImg++; showProgress(curImg, count); } function processFile1(path,listi,currtopcat, oldtopcat){ setColor(text_color[0], text_color[1], text_color[2]); //calculate text offset top_cat_text_offset = height_row*1.05; if(processcount<1){ //draw First category Top Level Label // increment row //row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; setFont("Helvetica", top_cat_text_size, "bold, antiliased"); start_text_x = start_x; start_text_y = row * (height_row + v_interval) + v_interval + top_cat_text_offset; drawString(currtopcat+" ", start_text_x, start_text_y); topcatwidth = getStringWidth(currtopcat+" "); row = row + 1; processcount++; } if(currtopcat != oldtopcat){ // increment row row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; setFont("Helvetica", top_cat_text_size, "bold, antiliased"); start_text_x = start_x; start_text_y = row * (height_row + v_interval) + v_interval + top_cat_text_offset; drawString(currtopcat+" ", start_text_x, start_text_y); topcatwidth = getStringWidth(currtopcat+" "); row = row + 1; } // Check for row overflow, start new row if needed if ((total_x_width + n_width) > montage_width) { // increment row row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; } print(path); open(path); id=getImageID; img_width = getWidth; img_height = getHeight; n_width = round((img_width * scaled_height)/img_height); run("Size...", "width=" + n_width + " height=" + scaled_height + " average interpolation=Bicubic"); // get image width and height after it was scaled n_width = getWidth; n_height = getHeight; start_x = total_x_width; start_y = row * (height_row + v_interval) + v_interval; run("Select All"); run("Copy"); selectImage(id_plot); makeRectangle(start_x, start_y, n_width, n_height); run("Paste"); selectImage(id); close(); // update display updateDisplay(); total_x_width = total_x_width + n_width + h_interval; if (save_files_flag == 1) { selectImage(id_plot); path_files = dir_anim + "frame_" + curImg; saveAs("PNG", path_files); print("image " + curImg + " saved"); } curImg++; showProgress(curImg, count); } function processFile2(path,listi,currtopcat, oldtopcat, currseccat, oldseccat){ setColor(text_color[0], text_color[1], text_color[2]); //calculate text size sec_cat_text_size = top_cat_text_size*0.5; //calculate text offset top_cat_text_offset = height_row *1.2; sec_cat_text_offset = height_row; if(processcount<1){ //draw First category Top Level Label // increment row //row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; setFont("Helvetica", top_cat_text_size, "bold, antiliased"); start_text_x = start_x; start_text_y = row * (height_row + v_interval) + v_interval + top_cat_text_offset; drawString(currtopcat, start_text_x, start_text_y); row = row + 1; //draw First category Second Level Label // increment row //row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; if(currseccat == " "){ row = row - 1; } setFont("Helvetica", sec_cat_text_size, "bold, antiliased"); start_text_x = start_x; start_text_y = row * (height_row + v_interval) + v_interval + sec_cat_text_offset; drawString(currseccat, start_text_x, start_text_y); row = row + 1; processcount++; } if(currtopcat != oldtopcat){ // increment row row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; setFont("Helvetica", top_cat_text_size, "bold, antiliased"); start_text_x = start_x; start_text_y = row * (height_row + v_interval) + v_interval + top_cat_text_offset; drawString(currtopcat, start_text_x, start_text_y); } if(currseccat != oldseccat || currtopcat != oldtopcat){ if(currseccat == " "){ row = row - 1; } // increment row row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; setFont("Helvetica", sec_cat_text_size, "bold, antiliased"); start_text_x = start_x; start_text_y = row * (height_row + v_interval) + v_interval + sec_cat_text_offset; drawString(currseccat, start_text_x, start_text_y); row = row + 1; } // Check for row overflow, start new row if needed if ((total_x_width + n_width) > montage_width) { // increment row row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; } open(path); id=getImageID; img_width = getWidth; img_height = getHeight; n_width = round((img_width * scaled_height)/img_height); run("Size...", "width=" + n_width + " height=" + scaled_height + " average interpolation=Bicubic"); // get image width and height after it was scaled n_width = getWidth; n_height = getHeight; start_x = total_x_width; start_y = row * (height_row + v_interval) + v_interval; run("Select All"); run("Copy"); selectImage(id_plot); makeRectangle(start_x, start_y, n_width, n_height); run("Paste"); selectImage(id); close(); // update display updateDisplay(); total_x_width = total_x_width + n_width + h_interval; if (save_files_flag == 1) { selectImage(id_plot); path_files = dir_anim + "frame_" + curImg; saveAs("PNG", path_files); print("image " + curImg + " saved"); } curImg++; showProgress(curImg, count); } function processFile3(path,listi,currtopcat, oldtopcat, currseccat, oldseccat, currthirdcat, oldthirdcat){ setColor(text_color[0], text_color[1], text_color[2]); //calculate text size sec_cat_text_size = top_cat_text_size*0.75; third_cat_text_size = top_cat_text_size*0.50; //calculate text offset top_cat_text_offset = height_row*1.3; sec_cat_text_offset = height_row*1.4; third_cat_text_offset = height_row; //draw First category Top Level Label if(currseccat == " "){ top_cat_text_offset = height_row; } if(currthirdcat == " "){ sec_cat_text_offset = height_row*1.05; } if(processcount<1){ // increment row //row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; setFont("Helvetica", top_cat_text_size, "bold, antiliased"); start_text_x = start_x; start_text_y = row * (height_row + v_interval) + v_interval + top_cat_text_offset; drawString(currtopcat, start_text_x, start_text_y); row = row + 1; //draw First category Second Level Label // increment row //row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; setFont("Helvetica", sec_cat_text_size, "bold, antiliased"); start_text_x = start_x; start_text_y = row * (height_row + v_interval) + v_interval + sec_cat_text_offset - getValue("font.height"); if(currseccat == " "){ row = row - 1; } drawString(currseccat, start_text_x, start_text_y); //draw First category Third Level Label // increment row row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; setFont("Helvetica", third_cat_text_size, "bold, antiliased"); start_text_x = start_x; start_text_y = row * (height_row + v_interval) + v_interval + third_cat_text_offset; drawString(currthirdcat, start_text_x, start_text_y); if(currthirdcat == " "){ row = row - 1; } row= row + 1; processcount++; } if(currtopcat != oldtopcat){ // increment row row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; setFont("Helvetica", top_cat_text_size, "bold, antiliased"); start_text_x = start_x; start_text_y = row * (height_row + v_interval) + v_interval + top_cat_text_offset; drawString(currtopcat, start_text_x, start_text_y); } if(currseccat != oldseccat || currtopcat != oldtopcat){ if(currseccat == " "){ row = row - 1; } // increment row row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; setFont("Helvetica", sec_cat_text_size, "bold, antiliased"); start_text_x = start_x; start_text_y = row * (height_row + v_interval) + v_interval + sec_cat_text_offset; drawString(currseccat, start_text_x, start_text_y); } if(currthirdcat != oldthirdcat || currseccat != oldseccat || currtopcat != oldtopcat){ if(currthirdcat == " "){ row = row - 1; } // increment row row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; setFont("Helvetica", third_cat_text_size, "bold, antiliased"); start_text_x = start_x; start_text_y = row * (height_row + v_interval) + v_interval + third_cat_text_offset; drawString(currthirdcat, start_text_x, start_text_y); row = row + 1; } // Check for row overflow, start new row if needed if ((total_x_width + n_width) > montage_width) { // increment row row = row + 1; // reset column start_x = 0; // reset total row width total_x_width = 0; } open(path); id=getImageID; img_width = getWidth; img_height = getHeight; n_width = round((img_width * scaled_height)/img_height); run("Size...", "width=" + n_width + " height=" + scaled_height + " average interpolation=Bicubic"); // get image width and height after it was scaled n_width = getWidth; n_height = getHeight; start_x = total_x_width; start_y = row * (height_row + v_interval) + v_interval; run("Select All"); run("Copy"); selectImage(id_plot); makeRectangle(start_x, start_y, n_width, n_height); run("Paste"); selectImage(id); close(); // update display updateDisplay(); total_x_width = total_x_width + n_width + h_interval; if (save_files_flag == 1) { selectImage(id_plot); path_files = dir_anim + "frame_" + curImg; saveAs("PNG", path_files); print("image " + curImg + " saved"); } curImg++; showProgress(curImg, count); } run("Select None"); setBatchMode(false);