[Plugins-java] How to get a color from current/specific lut using an index

Hello!

I want to paint a vectorial map on my image emphasizing the greatest length vectors. For that i want to apply a color lut based on length, so how can i obtain the colors from current/specific LUT to assign that color to the segment based on its length?? I cant find any IJ.getcolorfromvalue(int value) function or similar, where value is in range 0-255.
I tried my best to explain my problem, regards

You can get the LUT from the current ImageProcessor and then query this LUT for any value in the 0-255 range. Here’s a Groovy script illustrating this (just run it from the script editor):

// @ImagePlus imp

lut = imp.getProcessor().getLut()

30.step(250, 50) { value ->
	println ("Value: " + value +
		" RGB: " + lut.getRGB(value) +
		" R " + lut.getRed(value) +
		" G " + lut.getGreen(value) +
		" B " + lut.getBlue(value))
}

Ok, that works for the ImageProcessor intrinsic LUT, here is the java code

  LUT lut = ip.getLut();
//...and then
  Line l = new Line(0.5 + cal.getRawX(gridpoint.getX()), 0.5 + cal.getRawY(gridpoint.getY()),
                        0.5 + cal.getRawX(fp[pos].getX()), 0.5 + cal.getRawY(fp[pos].getY()));
  int icolor = (int) Math.min(255, Math.max(0, length/DotSpacingmm.getPolarRadius()*255));
  l.setStrokeColor(new Color(lut.getRGB(icolor)));

Now I just need to know how to get an specific LUT from the installed ones, I just have the names using

   IJ.getLuts();

So I need to build a LUT object using a given name from this list

You can use the LutLoader.openLut(String pathOrURL) method, for example.

Doesnt work!! :frowning: the LutLoader.openLut(String pathOrURL) specifically ask for a filepath or a url, does not work with inlined strings. I solved using the code inside it, (I wonder why they didnt make a simple public method for this??):

int primaryColor(int color, byte[] reds, byte[] greens, byte[] blues) {
        for (int i = 0; i < 256; i++) {
            if ((color & 4) != 0) {
                reds[i] = (byte) i;
            }
            if ((color & 2) != 0) {
                greens[i] = (byte) i;
            }
            if ((color & 1) != 0) {
                blues[i] = (byte) i;
            }
        }
        return 256;
    }

//... and then
        FileInfo fi = new FileInfo();
        fi.reds = new byte[256];
        fi.greens = new byte[256];
        fi.blues = new byte[256];
        fi.lutSize = 256;
        int nColors = primaryColor(6, fi.reds, fi.greens, fi.blues);
        LUT lut = new LUT(fi.reds, fi.greens, fi.blues);

//... now you can call
       l.setStrokeColor(new Color(lut.getRGB(icolor)));

Absolutely, that’s what it says in the javadoc.

Sorry, I don’t understand: if you only need a primary color, you don’t need the whole LUT stuff at all, just scale your index to the range 0-255 and set a new Color, no? Maybe it would’ve been useful if you shared your final goal from the beginning, as it’s still not clear to me what you actually want to achieve with that.

LutLoader gives you the freedom of loading whichever .lut file you want, e.g. from the luts directory in ImageJ, or from anywhere else.

If you only want a few standard LUTs, you can also use LOCI’s ColorUtil class.


By the way, I just found that you can also use ImageJ2’s LUTService which will give you an imglib2 ColorTable. Here’s my updated Groovy script:

// @LUTService ls

import net.imglib2.display.ColorTable

lutMap = ls.findLUTs()

colorTable = ls.loadLUT(lutMap.get("Green.lut"))

30.step(250, 50) { value ->
println ("Value: " + value +
		" R " + colorTable.get(ColorTable.RED, value) +
		" G " + colorTable.get(ColorTable.GREEN, value) +
		" B " + colorTable.get(ColorTable.BLUE, value))
}
1 Like

The problem with LutLoader is that changes the whole LUT, I want to draw a vector map in my image using a predefined lut leaving the image with its original lut. LutLoader also changes my image lut so was worthless. Your LUTService Solution is really good, here is the java code i use:


    LUTService ls = new DefaultLUTService();
    ColorTable ct = ls.loadLUT(ls.findLUTs().get(("Yellow.lut")));

//... and then
    l.setStrokeColor(new Color(ct.get(ColorTable.RED, icolor),ct.get(ColorTable.GREEN, icolor),ct.get(ColorTable.BLUE, icolor)));

Great that it’s useful to you!

In an ImageJ/SciJava plugin, you should never instantiate a new instance of a Service, but always use a SciJava parameter annotation @LUTService to retrieve the Service from your current Context.

1 Like

If I use:

    @Parameter
    private LUTService ls;

//... and then
    ColorTable ct = ls.loadLUT(ls.findLUTs().get(("Yellow.lut")));

then the plugin complains java.lang.NullPointerException, so how is the right thing to do??

Your plugin needs to implement org.scijava.command.Command.

The example-imagej-command project shows how to use parameter annotation:

1 Like

But doing that doesnt show anything in legacy mode. I can solve with the following Color_Table class:

import java.awt.Color;
import java.io.IOException;
import net.imagej.lut.DefaultLUTService;
import net.imagej.lut.LUTService;
import net.imglib2.display.ColorTable;
import org.scijava.plugin.Parameter;

/**
 *
 * @author alex.vergara
 */
public class Color_Table {

    private final Color[] CT;
    private final int size;

    @Parameter
    private final LUTService ls = new DefaultLUTService();

    public Color_Table(String colormap) throws IOException {
        ColorTable ct = ls.loadLUT(ls.findLUTs().get(colormap));
        size = ct.getLength();
        CT = new Color[size];
        for (int i = 0; i < size; i++) {
            CT[i] = new Color(ct.get(ColorTable.RED, i), ct.get(ColorTable.GREEN, i), ct.get(ColorTable.BLUE, i));
        }
    }

    public int getSize() {
        return size;
    }
    
    public Color getColor(int index){
        return CT[index];
    }

}

just create a new Color_Table object with the names and you can get the proper color back with the getcolor function, example:

Color_Table ct = new Color_Table("Yellow.lut");

//... and then
for (int i = 0; i < ct.getsize(); i++) {
    Color myColor = ct.getcolor(i);
}