/* # ImageMagick Posterizer If installed, uses ImageMagick to posterize images. v230222: 1st version f1-2: updated stripKnownExtensionFromString function. v230614: Works on stacks (multiple slices). f1: replace getDir for 1.54g10. v230822: Corrected selectImage to selectWindow. */ macroL = "IM_Posterizer_v230614-f1.ijm"; iMMagickPath = findAppPath("ImageMagick","magick.exe","not found"); if (iMMagickPath=="not found") exit("Sorry, the macro could not find the necessary ImageMagick files"); fS = File.separator; oName = stripKnownExtensionFromString(getTitle()); tempDir = getDirectory("temp"); getDimensions(imageWidth, imageHeight, channels, slices, frames); oImageTitle = getTitle(); oImageID = getImageID(); Dialog.create("Quantizing options \(" + macroL + "\)"); Dialog.addHelp("https://imagemagick.org/Usage/quantize/"); Dialog.addMessage("Resulting image will have " + slices + " slices"); posterActions = newArray("Reduce colors", "Uniform colors", "Color map", "Threshold"); Dialog.addRadioButtonGroup("Action:",posterActions,1,2,posterActions[0]); Dialog.addMessage("For'Uniform colors' each color channel is divided up using the input number"); Dialog.addNumber("Number of colors",256,0,3,"colors"); Dialog.addCheckbox("Monochrome?",false); Dialog.addCheckbox("Convert final image/stack to 8-bit",false); ditherOptions = newArray("None","FloydSteinberg","Riemersma"); Dialog.addRadioButtonGroup("Dither method:",ditherOptions,1,3,"None"); Dialog.addFile("If Color Map choose table image or web-safe Netscape palette", "Netscape"); Dialog.addNumber("Threshold level",50,0,3,"%"); Dialog.addCheckbox("Diagnostic mode",false); Dialog.show; pAction = Dialog.getRadioButton(); colorN = Math.constrain(Dialog.getNumber(),1,256); monoChrome = Dialog.getCheckbox(); pal = Dialog.getCheckbox(); colorTable = Dialog.getString(); thresholdP = Math.constrain(Dialog.getNumber(),1,256); ditherO = Dialog.getRadioButton(); diagnostics = Dialog.getCheckbox(); setBatchMode("true"); /* Create ImageMagick action strings */ suffix = ""; actionString = "clipboard:"; if (ditherO!="None"){ actionString += " -dither " + ditherO; suffix += "_dith" + substring(ditherO,0,2); } else actionString += " +dither "; if(pAction=="Reduce colors"){ actionString += " -colors " + colorN; suffix += "_R" + colorN; } else if (pAction=="Uniform colors"){ actionString += " -posterize " + colorN; suffix += "_P"+colorN; } else if (pAction=="Color map"){ if (colorTable=="") colorTable = File.openDialog("Please select color map file"); else colorTable = "netscape:"; actionString += "-remap " + colorTable; suffix += "_CMapped"; } else{ actionString = "clipboard: -separate -threshold " + thresholdP + "% -combine "; suffix += "_pThresh" + thresholdP; } if(monoChrome){ actionString += " -colorspace gray -normalize "; suffix += "_mono"; } fName = oName + suffix; tempPosterizerPath = tempDir + "tempIMPosterizer-" + oName + ".png"; execString = "\"" + iMMagickPath + "\" " + actionString + " \"" + tempPosterizerPath + "\""; if(diagnostics) IJ.log("IM execute string:\n" + execString); for (i=0;i1){ selectImage(oImageID); setSlice(1); selectWindow(fName); setSlice(1); } if (pal){ bD = bitDepth(); if (bD==24 && !is("grayscale")) run("8-bit Color", "number=" + minOf(256,colorN)); else if (is("grayscale")) run("8-bit", "number=" + minOf(256,colorN)); if (slices>1) run("Delete Slice"); } setBatchMode("exit and display"); beep();wait(100);beep();wait(300);beep(); call("java.lang.System.gc"); showStatus("IM posterizer finished"); /* End of ImageMagick Posterizer */ /* ( 8(|)) ( 8(|)) ( 8(|)) ASC Functions @@@@@:-) @@@@@:-) @@@@@:-) */ function addImageToStack(stackName,baseImage) { /* v230614: Added "Select None" */ run("Copy"); selectWindow(stackName); run("Add Slice"); run("Paste"); run("Select None"); selectWindow(baseImage); } function closeImageByTitle(windowTitle) { /* Cannot be used with tables */ /* v181002: reselects original image at end if open v200925: uses "while" instead of if so it can also remove duplicates v230411: checks to see if any images opn first. */ if(nImages>0){ oIID = getImageID(); while (isOpen(windowTitle)) { selectWindow(windowTitle); close(); } if (isOpen(oIID)) selectImage(oIID); } } function findAppPath(appName,appEx,defaultPath) { /* v210921 1st version: appName is assumed to be the app folder name, appEx is the executable, default is the default return value v211018: assumes specific executable path stored in prefs Prints message rather than exits when app not found v211213: fixed defaultPath error v211214: Adds additional location as packaged within a Fiji/IJ distribution v220121: Changed fS line v230803: Replaced getDir with getDirectory for ImageJ 1.54g10 */ functionL = "findAppPath_v230803"; fS = File.separator; ijPath = getDirectory("imagej"); appsPath = substring(ijPath,0,lengthOf(ijPath)-1); appsPath = substring(appsPath,0,lastIndexOf(appsPath,fS)); appFound = false; prefsName = "asc.external.paths." + toLowerCase(appName) + "." + appEx; appPath = call("ij.Prefs.get", prefsName, defaultPath); appLoc = ""+fS+appName+fS+appEx; cProg = "C:"+fS+"Program Files"; defAppPaths = newArray(cProg+fS+"Utilities"+appLoc,cProg+" \(x86\)"+fS+"Utilities"+appLoc,cProg+appLoc,cProg+" \(x86\)"+appLoc,appsPath+appLoc,ijPath+"Apps"+appLoc); if (!File.exists(appPath)) { for(i=0;i0){ protectedPath = substring(string,0,protectedPathEnd); string = substring(string,protectedPathEnd); } unusefulCombos = newArray("-", "_"," "); for (i=0; i=0) string = replace(string,combo,unusefulCombos[i]); } } if (lastIndexOf(string, ".")>0 || lastIndexOf(string, "_lzw")>0) { knownExts = newArray(".avi", ".csv", ".bmp", ".dsx", ".gif", ".jpg", ".jpeg", ".jp2", ".png", ".tif", ".txt", ".xlsx"); knownExts = Array.concat(knownExts,knownExts,"_transp","_lzw"); kEL = knownExts.length; for (i=0; i0){ preChan = substring(string,0,iChanLabels); postChan = substring(string,iChanLabels); while (indexOf(preChan,knownExts[i])>0){ preChan = replace(preChan,knownExts[i],""); string = preChan + postChan; } } } while (endsWith(string,knownExts[i])) string = "" + substring(string, 0, lastIndexOf(string, knownExts[i])); } } unwantedSuffixes = newArray(" ", "_","-"); for (i=0; i0){ if(!endsWith(protectedPath,fS)) protectedPath += fS; string = protectedPath + string; } return string; }