package ij;
import ij.process.*;
import ij.gui.*;
import ij.plugin.*;
import ij.plugin.frame.*;
import ij.io.FileInfo;
import java.awt.*;
import java.awt.image.*;
public class CompositeImage extends ImagePlus {
/** Display modes (note: TRANSPARENT mode has not yet been implemented) */
public static final int COMPOSITE=1, COLOR=2, GRAYSCALE=3, TRANSPARENT=4;
public static final int MAX_CHANNELS = 7;
int[] rgbPixels;
boolean newPixels;
MemoryImageSource imageSource;
Image awtImage;
WritableRaster rgbRaster;
SampleModel rgbSampleModel;
BufferedImage rgbImage;
ColorModel rgbCM;
ImageProcessor[] cip;
Color[] colors = {Color.red, Color.green, Color.blue, Color.white, Color.cyan, Color.magenta, Color.yellow};
LUT[] lut;
int currentChannel = -1;
int previousChannel;
int currentSlice = 1;
int currentFrame = 1;
boolean singleChannel;
boolean[] active = new boolean[MAX_CHANNELS];
int mode = COLOR;
int bitDepth;
double[] displayRanges;
byte[][] channelLuts;
boolean customLuts;
boolean syncChannels;
public CompositeImage(ImagePlus imp) {
this(imp, COLOR);
}
public CompositeImage(ImagePlus imp, int mode) {
if (modeGRAYSCALE)
mode = COLOR;
this.mode = mode;
int channels = imp.getNChannels();
bitDepth = getBitDepth();
if (IJ.debugMode) IJ.log("CompositeImage: "+imp+" "+mode+" "+channels);
ImageStack stack2;
boolean isRGB = imp.getBitDepth()==24;
if (isRGB) {
if (imp.getImageStackSize()>1)
throw new IllegalArgumentException("RGB stacks not supported");
stack2 = getRGBStack(imp);
} else
stack2 = imp.getImageStack();
int stackSize = stack2.getSize();
if (channels==1 && isRGB)
channels = 3;
if (channels==1 && stackSize<=MAX_CHANNELS && !imp.dimensionsSet)
channels = stackSize;
if (channels<1 || (stackSize%channels)!=0)
throw new IllegalArgumentException("stacksize not multiple of channels");
if (mode==COMPOSITE && channels>MAX_CHANNELS)
this.mode = COLOR;
compositeImage = true;
int z = imp.getNSlices();
int t = imp.getNFrames();
if (channels==stackSize || channels*z*t!=stackSize)
setDimensions(channels, stackSize/channels, 1);
else
setDimensions(channels, z, t);
setStack(imp.getTitle(), stack2);
setCalibration(imp.getCalibration());
FileInfo fi = imp.getOriginalFileInfo();
if (fi!=null) {
displayRanges = fi.displayRanges;
channelLuts = fi.channelLuts;
}
setFileInfo(fi);
Object info = imp.getProperty("Info");
if (info!=null)
setProperty("Info", imp.getProperty("Info"));
if (mode==COMPOSITE) {
for (int i=0; i0 && (stack2.getProcessor(1) instanceof ColorProcessor)) { // RGB?
cip = null;
lut = null;
return;
}
setupLuts(channels);
if (mode==COMPOSITE) {
cip = new ImageProcessor[channels];
for (int i=0; iMAX_CHANNELS?createLutFromColor(Color.white):null;
for (int i=0; istack2.getSize() || channels>MAX_CHANNELS)
return;
for (int i=0; inChannels) ch = nChannels;
boolean newChannel = false;
if (ch-1!=currentChannel) {
previousChannel = currentChannel;
currentChannel = ch-1;
newChannel = true;
}
ImageProcessor ip = getProcessor();
if (mode!=COMPOSITE) {
if (newChannel) {
setupLuts(nChannels);
LUT cm = lut[currentChannel];
if (mode==COLOR)
ip.setLut(cm);
if (!(cm.min==0.0&&cm.max==0.0))
ip.setMinAndMax(cm.min, cm.max);
if (!IJ.isMacro()) ContrastAdjuster.update();
for (int i=0; i=nChannels) {
setSlice(1);
currentChannel = 0;
newChannel = true;
}
bitDepth = getBitDepth();
}
if (newChannel) {
getProcessor().setMinAndMax(cip[currentChannel].getMin(), cip[currentChannel].getMax());
if (!IJ.isMacro()) ContrastAdjuster.update();
}
//IJ.log(nChannels+" "+ch+" "+currentChannel+" "+newChannel);
if (getSlice()!=currentSlice || getFrame()!=currentFrame) {
currentSlice = getSlice();
currentFrame = getFrame();
int position = getStackIndex(1, currentSlice, currentFrame);
if (cip==null) return;
for (int i=0; icip.length)
return;
for (int i=1; i=0; i--)
sb.copyBits(cip[i], 0, 0, Blitter. OR);
}
img = ip.createImage();
singleChannel = false;
}
*/
ImageStack getRGBStack(ImagePlus imp) {
ImageProcessor ip = imp.getProcessor();
int w = ip.getWidth();
int h = ip.getHeight();
int size = w*h;
byte[] r = new byte[size];
byte[] g = new byte[size];
byte[] b = new byte[size];
((ColorProcessor)ip).getRGB(r, g, b);
ImageStack stack = new ImageStack(w, h);
stack.addSlice("Red", r);
stack.addSlice("Green", g);
stack.addSlice("Blue", b);
stack.setColorModel(ip.getDefaultColorModel());
return stack;
}
public LUT createLutFromColor(Color color) {
return LUT.createLutFromColor(color);
}
LUT createLutFromBytes(byte[] bytes) {
if (bytes==null || bytes.length!=768)
return createLutFromColor(Color.white);
byte[] r = new byte[256];
byte[] g = new byte[256];
byte[] b = new byte[256];
for (int i=0; i<256; i++) r[i] = bytes[i];
for (int i=0; i<256; i++) g[i] = bytes[256+i];
for (int i=0; i<256; i++) b[i] = bytes[512+i];
return new LUT(r, g, b);
}
public Color getChannelColor() {
if (lut==null || mode==GRAYSCALE)
return Color.black;
IndexColorModel cm = lut[getChannelIndex()];
if (cm==null)
return Color.black;
int index = cm.getMapSize() - 1;
int r = cm.getRed(index);
int g = cm.getGreen(index);
int b = cm.getBlue(index);
//IJ.log(index+" "+r+" "+g+" "+b);
if (r<100 || g<100 || b<100)
return new Color(r, g, b);
else
return Color.black;
}
public ImageProcessor getProcessor(int channel) {
if (cip==null || channel>cip.length)
return null;
else
return cip[channel-1];
}
public boolean[] getActiveChannels() {
return active;
}
public synchronized void setMode(int mode) {
if (modeGRAYSCALE)
return;
if (mode==COMPOSITE && getNChannels()>MAX_CHANNELS)
mode = COLOR;
for (int i=0; ilut.length)
throw new IllegalArgumentException("Channel out of range: "+channel);
return lut[channel-1];
}
/* Returns the LUT used by the current channel. */
public LUT getChannelLut() {
int c = getChannelIndex();
return lut[c];
}
/* Returns a copy of this image's channel LUTs as an array. */
public LUT[] getLuts() {
int channels = getNChannels();
if (lut==null) setupLuts(channels);
LUT[] luts = new LUT[channels];
for (int i=0; iMAX_CHANNELS && getMode()==COMPOSITE)
setMode(COLOR);
setup(nChannels, getImageStack());
}
/* Sets the LUT of the current channel. */
public void setChannelLut(LUT table) {
int c = getChannelIndex();
double min = lut[c].min;
double max = lut[c].max;
lut[c] = table;
lut[c].min = min;
lut[c].max = max;
if (mode==COMPOSITE && cip!=null && clut.length)
throw new IllegalArgumentException("Channel out of range");
lut[channel-1] = (LUT)table.clone();
if (getWindow()!=null && channel==getChannel())
getProcessor().setLut(lut[channel-1]);
if (cip!=null && cip.length>=channel && cip[channel-1]!=null)
cip[channel-1].setLut(lut[channel-1]);
else
cip = null;
customLuts = true;
}
/* Sets the IndexColorModel of the current channel. */
public void setChannelColorModel(IndexColorModel cm) {
setChannelLut(new LUT(cm,0.0,0.0));
}
public void setDisplayRange(double min, double max) {
ip.setMinAndMax(min, max);
int c = getChannelIndex();
lut[c].min = min;
lut[c].max = max;
if (getWindow()==null && cip!=null && c
Ads help maintain this website.