|
CompositeImage |
|
package ij;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import java.awt.image.*;
import ij.plugin.*;
import ij.plugin.frame.ContrastAdjuster;
public class CompositeImage extends ImagePlus {
int[] awtImagePixels;
boolean newPixels;
MemoryImageSource imageSource;
ColorModel imageColorModel;
Image awtImage;
int[][] pixels;
ImageProcessor[] cip;
Color[] colors = {Color.red, Color.green, Color.blue, Color.white, Color.cyan, Color.magenta, Color.yellow};
int currentChannel = 0;
static int count;
boolean singleChannel;
public CompositeImage(ImagePlus imp, int channels) {
//count++; if (count==1) throw new IllegalArgumentException("");
ImageStack stack2;
boolean isRGB = imp.getBitDepth()==24;
if (isRGB)
stack2 = getRGBStack(imp);
else
stack2 = imp.getStack();
int stackSize = stack2.getSize();
if (channels<2 || (stackSize%channels)!=0)
throw new IllegalArgumentException("channels<2 or stacksize not multiple of channels");
compositeImage = true;
setDimensions(channels, stackSize/channels, 1);
setup(channels, stack2);
setStack(imp.getTitle(), stack2);
setCalibration(imp.getCalibration());
Object info = imp.getProperty("Info");
if (info!=null)
setProperty("Info", imp.getProperty("Info"));
}
public Image getImage() {
if (img==null)
updateImage();
return img;
}
public void updateChannelAndDraw() {
singleChannel = true;
updateAndDraw();
}
public ImageProcessor getChannelProcessor() {
return cip[currentChannel];
}
void setup(int channels, ImageStack stack2) {
cip = new ImageProcessor[channels];
for (int i=0; i<channels; ++i) {
cip[i] = stack2.getProcessor(i+1);
cip[i].resetMinAndMax();
cip[i].setColorModel(createModelFromColor(colors[i]));
}
}
public void updateImage() {
int imageSize = width*height;
int nChannels = getNChannels();
int redValue, greenValue, blueValue;
int slice = getCurrentSlice();
if (nChannels==1) {
pixels = null;
awtImagePixels = null;
if (ip!=null)
img = ip.createImage();
return;
}
if (cip!=null && cip[0].getWidth()!=width||cip[0].getHeight()!=height||(pixels!=null&&pixels.length!=nChannels)) {
setup(nChannels, getStack());
pixels = null;
awtImagePixels = null;
if (slice>nChannels) {
setSlice(1);
slice = 1;
}
}
if (slice>nChannels) slice = nChannels;
if (slice-1!=currentChannel) {
currentChannel = slice-1;
getProcessor().setMinAndMax(cip[currentChannel].getMin(), cip[currentChannel].getMax());
ContrastAdjuster.update();
}
//IJ.log(nChannels+" "+slice+" "+currentChannel);
if (awtImagePixels == null) {
awtImagePixels = new int[imageSize];
newPixels = true;
imageSource = null;
}
if (pixels==null || pixels.length!=nChannels || pixels[0].length!=imageSize) {
pixels = new int[nChannels][];
for (int i=0; i<nChannels; ++i)
pixels[i] = new int[imageSize];
}
ImageProcessor ip = getProcessor();
cip[currentChannel].setMinAndMax(ip.getMin(),ip.getMax());
if (singleChannel) {
PixelGrabber pg = new PixelGrabber(cip[currentChannel].createImage(), 0, 0, width, height, pixels[currentChannel], 0, width);
try { pg.grabPixels();}
catch (InterruptedException e){};
} else {
for (int i=0; i<nChannels; ++i) {
PixelGrabber pg = new PixelGrabber(cip[i].createImage(), 0, 0, width, height, pixels[i], 0, width);
try { pg.grabPixels();}
catch (InterruptedException e){};
}
}
if (singleChannel && nChannels<=3) {
switch (currentChannel) {
case 0:
for (int i=0; i<imageSize; ++i) {
redValue = (pixels[0][i]>>16)&0xff;
awtImagePixels[i] = (awtImagePixels[i]&0xff00ffff) | (redValue<<16);
}
break;
case 1:
for (int i=0; i<imageSize; ++i) {
greenValue = (pixels[1][i]>>8)&0xff;
awtImagePixels[i] = (awtImagePixels[i]&0xffff00ff) | (greenValue<<8);
}
break;
case 2:
for (int i=0; i<imageSize; ++i) {
blueValue = pixels[2][i]&0xff;
awtImagePixels[i] = (awtImagePixels[i]&0xffffff00) | blueValue;
}
break;
}
} else {
for (int i=0; i<imageSize; ++i) {
redValue=0; greenValue=0; blueValue=0;
for (int j=0; j<nChannels; ++j) {
redValue += (pixels[j][i]>>16)&0xff;
greenValue += (pixels[j][i]>>8)&0xff;
blueValue += (pixels[j][i])&0xff;
if (redValue>255) redValue = 255;
if (greenValue>255) greenValue = 255;
if (blueValue>255) blueValue = 255;
}
awtImagePixels[i] = (redValue<<16) | (greenValue<<8) | (blueValue);
}
}
if (imageSource==null) {
imageColorModel = new DirectColorModel(32, 0xff0000, 0xff00, 0xff);
imageSource = new MemoryImageSource(width, height, imageColorModel, awtImagePixels, 0, width);
imageSource.setAnimated(true);
imageSource.setFullBufferUpdates(true);
awtImage = Toolkit.getDefaultToolkit().createImage(imageSource);
newPixels = false;
} else if (newPixels){
imageSource.newPixels(awtImagePixels, imageColorModel, 0, width);
newPixels = false;
} else
imageSource.newPixels();
if (img == null && awtImage!=null)
img = awtImage;
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 static IndexColorModel createModelFromColor(Color color) {
byte[] rLut = new byte[256];
byte[] gLut = new byte[256];
byte[] bLut = new byte[256];
int red = color.getRed();
int green = color.getGreen();
int blue = color.getBlue();
double rIncr = ((double)red)/255d;
double gIncr = ((double)green)/255d;
double bIncr = ((double)blue)/255d;
for (int i=0; i<256; ++i) {
rLut[i] = (byte)(i*rIncr);
gLut[i] = (byte)(i*gIncr);
bLut[i] = (byte)(i*bIncr);
}
return new IndexColorModel(8, 256, rLut, gLut, bLut);
}
public Color getChannelColor() {
int index = getCurrentSlice()-1;
if (index<colors.length && colors[index]!=Color.white)
return colors[index];
else;
return Color.black;
}
public ImageProcessor getProcessor(int channel) {
if (cip==null || channel>cip.length)
return null;
else
return cip[channel-1];
}
public double getMin(int channel) {
if (cip==null || channel>cip.length)
return 0.0;
else
return cip[channel-1].getMin();
}
public double getMax(int channel) {
if (cip==null || channel>cip.length)
return 0.0;
else
return cip[channel-1].getMax();
}
}
|
CompositeImage |
|