Good day Coral,
after having struggled with some aspects that may be less important for you but essential for a more general user group I’m able to provide an ImageJ-macro that writes a table to an image. The number of parameters has been minimized, i.e. one could perhaps think of colour choices for text and background …
To get an idea of what is provided, here is a screen shot of the macro-dialog:
- The first drop-down menu lists all tables that are open in ImageJ:
Choose the source table!
(The macro can deal with standard tables that are not titled “Results” such as the “Counts”-table.) - The second drop-down menu lists all images that are open in ImageJ:
Choose the destination image! - The third drop-down menu lists five schemes for the table position in the image:
Choose the destination position!
(Four corners are possible and a free position that must be set by hand.) - The desired font size can be set.
Set the size of the table font! - The opacity of the table can be set.
Set the opacity of the table!
Here is what your table looks like:
And here is how it looks like when positioned in your image at the top-right position:
Please note that the table data is written to the image as an overlay which means that you can hide and show or remove it (“Image >> Overlay >> Hide/Show/Remove Overlay”). However, this is only possible if you save the image with its overlay in TIF-format. If you want to make the overlay permanent, you need to flatten the image (“Image >> Overlay >> Flatten”). Then you can save it in arbitrary formats (e.g. the image above in JPG-format) but you lose the ability to hide or remove the overlay.
Here is your image with the overlay in TIF-format:
Capture_wOverlay.tif.zip (2.4 MB)
Finally, the macro code:
/* imagej-macro "table2image" (Herbie G., 21. April 2018) */
requires("1.51w");
setBatchMode(true);
saveSettings();
wnds = getList("window.titles");
wnds = Array.trim(wnds, listResultWnds(wnds));
if (wnds.length<1) exit("No table!");
imgs = getList("image.titles");
if (imgs.length<1) exit("No image!");
pos = newArray("Top-Left","Top-Right","Bottom-Left","Bottom-Right","Manually");
fntSz = 18;
opac = 80;
Dialog.create("table2image");
Dialog.addChoice("Overlay table", wnds, wnds[0]);
Dialog.addChoice("to Image", imgs, imgs[0]);
Dialog.addChoice("at Position", pos, pos[0]);
Dialog.addNumber("Font size", fntSz, 0, 2, "points");
Dialog.addNumber("Opacity (0...100)", opac, 0, 3, "%");
Dialog.show();
table = Dialog.getChoice();
imge = Dialog.getChoice();
posit = Dialog.getChoice();
fntSz = round(Dialog.getNumber());
opac = round(Dialog.getNumber());
rslts = isOpen("Results");
if (table!="Results") { renameTables(table, rslts, true); re=true; } else re=false;
run("Input/Output...", "jpeg=85 gif=-1 file=.txt copy_column copy_row save_column save_row");
setFont("Monospaced", fntSz);
setColor("black");
chrW = getStringWidth("0");
colsCnt = columnCount();
String.copyResults;
tbl = String.paste;
rows = split(tbl,"\n");
rowCnt = rows.length;
if (re) renameTables(table, rslts, false);
mxLen = newArray(colsCnt);
for ( j=0; j<rowCnt; j++ ) {
vals = split(rows[j],"\t");
for ( i=0; i<colsCnt; i++ ) {
len = getStringWidth(vals[i]);
if ( len>mxLen[i] ) mxLen[i]=len;
}
}
tblStr = " ";
for ( j=0; j<rowCnt; j++ ) {
vals = split(rows[j],"\t");
for ( i=0; i<colsCnt; i++ ) {
len = getStringWidth(vals[i]);
tblStr += vals[i];
blnkCnt = round(mxLen[i] - len)/chrW + 2;
for ( k=1; k<blnkCnt; k++ ) tblStr += " ";
}
if (j<rowCnt-1) tblStr += "\n ";
}
rows = split(tblStr,"\n");
w = getStringWidth(rows[0]) + 20;
newImage("data", "8-bit black", w, 1.2*rowCnt*fntSz, 1);
drawString(tblStr, 10, round(1.2*fntSz), "white");
doWand(0, 15);
run("Crop");
selectImage(imge);
run("Restore Selection");
coord = newArray(2);
tablePosition( coord, posit, pos );
run("Add Image...", "image=data x="+coord[0]+" y="+coord[1]+" opacity="+opac);
run("Select None");
close("data");
restoreSettings;
setBatchMode(false);
exit();
//////////////////////////
function listResultWnds( lst ) {
k = 0;
for ( i=0; i<lst.length; i++ ) {
selectWindow(lst[i]);
if (getInfo("window.type")=="ResultsTable") {
lst[k] = lst[i];
k++;
}
}
return k;
}
function renameTables( nme, rslt, dir ) {
r = "Results";
z = "ResultsZ";
if (dir) {
if (rslt) IJ.renameResults(z);
IJ.renameResults(nme, r);
} else {
IJ.renameResults(nme);
if (rslt) IJ.renameResults(z, r);
selectWindow(nme);
}
}
function columnCount() {
str = String.getResultsHeadings;
str = split(str, "\t");
return str.length;
}
function tablePosition( crd, p, pA ) {
getSelectionBounds(x, y, wS, hS);
b = 5;
w = getWidth();
h = getHeight();
if (p== pA[0]) {
crd[0] = b; crd[1] = b;
} else {
if (p== pA[1]) {
crd[0] = w-wS-b; crd[1] = b;
} else {
if (p== pA[2]) {
crd[0] = b; crd[1] = h-hS-b;
} else {
if (p== pA[3]) {
crd[0] = w-wS-b; crd[1] = h-hS-b;
} else {
setSelectionLocation((w-wS)*0.5, (h-hS)*0.5);
waitForUser("Position the selection.");
getSelectionBounds(x, y, wS, hS);
crd[0]=x; crd[1]=y;
}
}
}
}
}
/* imagej-macro "table2image" (Herbie G., 21. April 2018) */
Paste the above macro code to an empty macro window (Plugins >> New >> Macro) and run it. You may install the macro, after saving it as “_table2image.ijm”, by “Plugins >> Macros >> Install…”
Please tell me if you encounter any problems.
Regards
Herbie