
ij.plugin.LUT_Editor Maven / Gradle / Ivy
package ij.plugin;
import ij.*;
import ij.process.*;
import ij.gui.*;
import ij.plugin.frame.Recorder;
import java.awt.*;
import java.awt.image.*;
import ij.util.*;
import ij.measure.*;
import java.util.Vector;
import java.awt.event.*;
public class LUT_Editor implements PlugIn, ActionListener{
private ImagePlus imp;
Button openButton, saveButton, resizeButton, invertButton;
ColorPanel colorPanel;
int bitDepth;
public void run(String args) {
ImagePlus imp = WindowManager.getCurrentImage();
if (imp==null) {
IJ.showMessage("LUT Editor", "No images are open");
return;
}
bitDepth = imp.getBitDepth();
if (bitDepth==24) {
IJ.showMessage("LUT Editor", "RGB images do not use LUTs");
return;
}
if (bitDepth!=8) {
imp.getProcessor().resetMinAndMax();
imp.updateAndDraw();
}
colorPanel = new ColorPanel(imp);
if (colorPanel.getMapSize()!=256) {
IJ.showMessage("LUT Editor", "LUT must have 256 entries");
return;
}
boolean recording = Recorder.record;
Recorder.record = false;
int red=0, green=0, blue=0;
GenericDialog gd = new GenericDialog("LUT Editor");
Panel buttonPanel = new Panel(new GridLayout(4, 1, 0, 5));
openButton = new Button("Open...");
openButton.addActionListener(this);
buttonPanel.add(openButton);
saveButton = new Button("Save...");
saveButton.addActionListener(this);
buttonPanel.add(saveButton);
resizeButton = new Button("Set...");
resizeButton.addActionListener(this);
buttonPanel.add(resizeButton);
invertButton = new Button("Invert...");
invertButton.addActionListener(this);
buttonPanel.add(invertButton);
Panel panel = new Panel();
panel.add(colorPanel);
panel.add(buttonPanel);
gd.addPanel(panel, GridBagConstraints.CENTER, new Insets(10, 0, 0, 0));
gd.showDialog();
Recorder.record = recording;
if (gd.wasCanceled()){
colorPanel.cancelLUT();
return;
} else
colorPanel.applyLUT();
}
void save() {
try {IJ.run("LUT...");} // File>Save As>Lut...
catch(RuntimeException e) {}
}
public void actionPerformed(ActionEvent e) {
Object source = e.getSource();
if (source==openButton)
colorPanel.open();
else if (source==saveButton)
save();
else if (source==resizeButton)
colorPanel.resize();
else if (source==invertButton)
colorPanel.invert();
}
}
class ColorPanel extends Panel implements MouseListener, MouseMotionListener{
static final int entryWidth=12, entryHeight=12;
int rows = 16;
int columns = 16;
Color c[] = new Color[256];
Color b;
ColorProcessor cp;
IndexColorModel origin;
private ImagePlus imp;
private int[] xSize = new int[256], redY, greenY, blueY;
private int mapSize, x, y, initialC = -1, finalC = -1;
private byte[] reds, greens, blues;
private boolean updateLut;
private static String[] choices = {"Replication","Interpolation", "Spline Fitting"};
private static String scaleMethod = choices[1];
private int bitDepth;
ColorPanel(ImagePlus imp) {
setup(imp);
}
public void setup(ImagePlus imp) {
if (imp==null) {
IJ.noImage();
return;
}
this.imp = imp;
bitDepth = imp.getBitDepth();
ImageProcessor ip = imp.getChannelProcessor();
IndexColorModel cm = (IndexColorModel)ip.getColorModel();
origin = cm;
mapSize = cm.getMapSize();
reds = new byte[256];
greens = new byte[256];
blues = new byte[256];
cm.getReds(reds);
cm.getGreens(greens);
cm.getBlues(blues);
addMouseListener(this);
addMouseMotionListener(this);
for(int index = 0; index < mapSize; index++)
c[index] = new Color(reds[index]&255, greens[index]&255, blues[index]&255);
}
public Dimension getPreferredSize() {
return new Dimension(columns*entryWidth, rows*entryHeight);
}
public Dimension getMinimumSize() {
return new Dimension(columns*entryWidth, rows*entryHeight);
}
int getMouseZone(int x, int y){
int horizontal = (int)x/entryWidth;
int vertical = (int)y/entryHeight;
int index = (columns*vertical + horizontal);
return index;
}
public void colorRamp() {
if (initialC>finalC) {
int tmp = initialC;
initialC = finalC;
finalC = tmp;
}
float difference = finalC - initialC+1;
int start = (byte)c[initialC].getRed()&255;
int end = (byte)c[finalC].getRed()&255;
float rstep = (end-start)/difference;
for(int index = initialC; index <= finalC; index++)
reds[index] = (byte)(start+ (index-initialC)*rstep);
start = (byte)c[initialC].getGreen()&255;
end = (byte)c[finalC].getGreen()&255;
float gstep = (end-start)/difference;
for(int index = initialC; index <= finalC; index++)
greens[index] = (byte)(start + (index-initialC)*gstep);
start = (byte)c[initialC].getBlue()&255;
end = (byte)c[finalC].getBlue()&255;
float bstep = (end-start)/difference;
for(int index = initialC; index <= finalC; index++)
blues[index] = (byte)(start + (index-initialC)*bstep);
for (int index = initialC; index <= finalC; index++)
c[index] = new Color(reds[index]&255, greens[index]&255, blues[index]&255);
repaint();
}
public void mousePressed(MouseEvent e){
x = (e.getX());
y = (e.getY());
initialC = getMouseZone(x,y);
}
public void mouseReleased(MouseEvent e){
x = (e.getX());
y = (e.getY());
finalC = getMouseZone(x,y);
if(initialC>=mapSize&&finalC>=mapSize) {
initialC = finalC = -1;
return;
}
if(initialC>=mapSize)
initialC = mapSize-1;
if(finalC>=mapSize)
finalC = mapSize-1;
if(finalC<0)
finalC = 0;
if (initialC == finalC) {
b = c[finalC];
ColorChooser cc = new ColorChooser("Color at Entry " + (finalC) , c[finalC] , false);
c[finalC] = cc.getColor();
if (c[finalC]==null){
c[finalC] = b;
}
colorRamp();
} else {
b = c[initialC];
ColorChooser icc = new ColorChooser("Initial Entry (" + (initialC)+")" , c[initialC] , false);
c[initialC] = icc.getColor();
if (c[initialC]==null){
c[initialC] = b;
initialC = finalC = -1;
return;
}
b = c[finalC];
ColorChooser fcc = new ColorChooser("Final Entry (" + (finalC)+")" , c[finalC] , false);
c[finalC] = fcc.getColor();
if (c[finalC]==null){
c[finalC] = b;
initialC = finalC = -1;
return;
}
colorRamp();
}
initialC = finalC = -1;
applyLUT();
}
public void mouseClicked(MouseEvent e){}
public void mouseEntered(MouseEvent e){}
public void mouseExited(MouseEvent e){}
public void mouseDragged(MouseEvent e){
x = (e.getX());
y = (e.getY());
finalC = getMouseZone(x,y);
IJ.showStatus("index=" + getIndex(finalC));
repaint();
}
public void mouseMoved(MouseEvent e) {
x = (e.getX());
y = (e.getY());
int entry = getMouseZone(x,y);
if (entryImport>Lut...
catch(RuntimeException e) {}
updateLut = true;
repaint();
}
void updateLut() {
IndexColorModel cm = (IndexColorModel)imp.getChannelProcessor().getColorModel();
if (mapSize == 0)
return;
cm.getReds(reds);
cm.getGreens(greens);
cm.getBlues(blues);
for(int i=0; i256) newSize =256;
scaleMethod = sgd.getNextChoice();
scale(reds, greens, blues, newSize);
mapSize = newSize;
for(int i=0; i255.0) v=255.0; reds[i] = (byte)v;
v = Math.round(sfGreens.evalSpline(xValues, greens2, mapSize, i));
if (v<0.0) v=0.0; if (v>255.0) v=255.0; greens[i] = (byte)v;
v = Math.round(sfBlues.evalSpline(xValues, blues2, mapSize, i));
if (v<0.0) v=0.0; if (v>255.0) v=255.0; blues[i] = (byte)v;
}
}
public void cancelLUT() {
if (mapSize == 0)
return;
origin.getReds(reds);
origin.getGreens(greens);
origin.getBlues(blues);
mapSize = 256;
applyLUT();
}
public void applyLUT() {
byte[] reds2=reds, greens2=greens, blues2=blues;
if (mapSize<256) {
reds2 = new byte[256];
greens2 = new byte[256];
blues2 = new byte[256];
for(int i = 0; i < mapSize; i++) {
reds2[i] = reds[i];
greens2[i] = greens[i];
blues2[i] = blues[i];
}
scale(reds2, greens2, blues2, 256);
}
IndexColorModel cm = new IndexColorModel(8, 256, reds2, greens2, blues2);
ImageProcessor ip = imp.getChannelProcessor();
ip.setColorModel(cm);
if (imp.isComposite())
((CompositeImage)imp).setChannelColorModel(cm);
if (imp.getStackSize()>1 && !imp.isComposite())
imp.getStack().setColorModel(cm);
imp.updateAndDraw();
}
public void update(Graphics g) {
paint(g);
}
public void paint(Graphics g) {
if (updateLut) {
updateLut();
updateLut = false;
}
int index = 0;
for (int y=0; y=mapSize) {
g.setColor(Color.lightGray);
g.fillRect(x*entryWidth, y*entryHeight, entryWidth, entryHeight);
} else if (((index <= finalC) && (index >= initialC)) || ((index >= finalC) && (index <= initialC))){
g.setColor(c[index].brighter());
g.fillRect(x*entryWidth, y*entryHeight, entryWidth, entryHeight);
g.setColor(Color.white);
g.drawRect((x*entryWidth), (y*entryHeight), entryWidth, entryHeight);
g.setColor(Color.black);
g.drawLine((x*entryWidth)+entryWidth-1, (y*entryHeight), (x*entryWidth)+entryWidth-1, (y*entryWidth)+entryHeight);
g.drawLine((x*entryWidth), (y*entryHeight)+entryHeight-1, (x*entryWidth)+entryWidth-1, (y*entryHeight)+entryHeight-1);
g.setColor(Color.white);
} else {
g.setColor(c[index]);
g.fillRect(x*entryWidth, y*entryHeight, entryWidth, entryHeight);
g.setColor(Color.white);
g.drawRect((x*entryWidth), (y*entryHeight), entryWidth-1, entryHeight-1);
g.setColor(Color.black);
g.drawLine((x*entryWidth), (y*entryHeight), (x*entryWidth)+entryWidth-1, (y*entryWidth));
g.drawLine((x*entryWidth), (y*entryHeight), (x*entryWidth), (y*entryHeight)+entryHeight-1);
}
index++;
}
}
}
int getMapSize() {
return mapSize;
}
}
© 2015 - 2025 Weber Informatics LLC | Privacy Policy