package ij.plugin;
import ij.*;
import ij.process.*;
import ij.gui.*;
import java.awt.*;
import ij.plugin.ChannelSplitter;
import java.awt.image.BufferedImage;
import java.awt.event.*;
import java.util.Vector;

/**
 * This plugin implements the Image/Colors/Arrange Channels command,
 *	which allows the user to change the order of channels.
 *
 * @author Norbert Vischer  23-sep-2012
 */
public class ChannelArranger implements PlugIn, TextListener {
	private ThumbnailsCanvas thumbNails;
	private String patternString;
	private String allowedDigits;
	private TextField orderField;
	private int nChannels;

	public void run(String arg) {
		ImagePlus imp = IJ.getImage();
		nChannels = imp.getNChannels();
		if (nChannels==1) {
			IJ.error("Channel Arranger", "Image must have more than one channel");
			return;
		}
		if (nChannels>9) {
			IJ.error("Channel Arranger", "This command does not work with more than 9 channels.");
			return;
		}
		patternString = "1234567890".substring(0, nChannels);
		allowedDigits = patternString;
		GenericDialog gd = new GenericDialog("Arrange Channels");
		thumbNails = new ThumbnailsCanvas(imp);
		Panel panel = new Panel();
		panel.add(thumbNails);
		gd.addPanel(panel);
		//gd.setInsets(20, 20, 5);
		gd.addStringField("New channel order:", allowedDigits);
		Vector v = gd.getStringFields();
		orderField = (TextField)v.elementAt(0);
		orderField.addTextListener(this);
		gd.addHelp(IJ.URL+"/docs/menus/image.html#arrange");
		gd.showDialog();
		if (gd.wasCanceled())
			return;
		String newOrder = gd.getNextString();
		int nChannels2 = newOrder.length();
		if (nChannels2==0)
			return;
		for (int i=0; i
		The following example opens the FluorescentCells sample  
		image and reverses the order of the channels.
		
		ImagePlus img = IJ.openImage("http://imagej.nih.gov/ij/images/FluorescentCells.zip");
		int[] order = {3,2,1};
		ImagePlus img2 = ChannelArranger.run(img, order);
		img2.setDisplayMode(IJ.COLOR);
		img2.show();
		
*/ public static ImagePlus run(ImagePlus img, int[] newOrder) { int channel = img.getChannel(); int slice = img.getSlice(); int frame = img.getFrame(); ImagePlus[] channels = ChannelSplitter.split(img); int nChannels2 = newOrder.length; if (nChannels2>channels.length) nChannels2 = channels.length; ImagePlus[] channels2 = new ImagePlus[nChannels2]; for (int i=0; i=channels.length) throw new IllegalArgumentException("value out of range:"+newOrder[i]); channels2[i] = channels[index]; } ImagePlus img2 = null; if (nChannels2==1) img2 = channels2[0]; else img2 = RGBStackMerge.mergeChannels(channels2, false); int mode2 = IJ.COLOR; if (img.isComposite()) mode2 = ((CompositeImage)img).getMode(); if (img2.isComposite()) ((CompositeImage)img2).setMode(mode2); if (channel<=nChannels2) { int channel2 = newOrder[channel-1]; img2.setPosition(channel2, slice, frame); } Overlay overlay = img.getOverlay(); if (overlay!=null) { for (int i=0; i=1 && c<=nChannels2) roi.setPosition(newOrder[c-1], z, t); } img2.setOverlay(overlay); } img.changes = false; img.close(); return img2; } public void textValueChanged(TextEvent e) { TextField tf = (TextField) e.getSource(); String typed = tf.getText(); if (typed.length()>nChannels) { orderField.setText(patternString); return; } for (int jj=0; jj hh) { iconHeight = iconWidth * hh / ww; dy = (iconWidth - iconHeight) / 2; } if (ww < hh) { iconWidth = iconHeight * ww / hh; dx = (iconHeight - iconWidth) / 2; } nChannels = cImp.getNChannels(); seq = seq.substring(0, nChannels); setSize((nChannels + 1) * iconSize, 2 * iconSize + 30); } public void update(Graphics g) { paint(g); } public void setSequence(String seq) { this.seq = seq; } public int[] getStackPos() { return new int[]{currentChannel, currentSlice, currentFrame}; } public void paint(Graphics g) { if (g == null) { return; } int savedMode = cImp.getMode(); if (savedMode==IJ.COMPOSITE) cImp.setMode(IJ.COLOR); BufferedImage bImg; ImageProcessor ipSmall; os = createImage((nChannels + 1) * iconSize, 2 * iconSize + 30); osg = os.getGraphics(); osg.setFont(ImageJ.SansSerif12); int y1; for (int chn = 1; chn <= nChannels; chn++) { cImp.setPositionWithoutUpdate(chn, currentSlice, currentFrame); cImp.updateImage(); ipSmall = cImp.getProcessor().resize(iconWidth, iconHeight, true); bImg = ipSmall.getBufferedImage(); int index = chn - 1; y1 = marginY; for (int row = 0; row < 2; row++) { if (index >= 0) { int xx = index * iconSize + marginX; osg.drawImage(bImg, xx + dx, y1 + dy, null); osg.setColor(Color.LIGHT_GRAY); osg.drawRect(xx, y1, iconSize, iconSize); osg.fillRoundRect(xx + iconSize / 2 - 4, y1 + iconSize - 22, 18, 18, 6, 6); osg.setColor(Color.BLACK); osg.drawRoundRect(xx + iconSize / 2 - 4, y1 + iconSize - 22, 18, 18, 6, 6); osg.drawString("" + chn, xx + 52, y1 + iconSize - 7); index = seq.indexOf("" + chn, 0); if (seq.indexOf("" + chn, index) == -1) {//char must not occur twice index = -1; } } y1 += (iconSize + separatorY); } } y1 = marginY + iconSize - 7; osg.drawString("Old:", 6, y1); y1 += (iconSize + separatorY); osg.drawString("New:", 6, y1); osg.dispose(); if (os == null) { return; } g.drawImage(os, 0, 0, this); if (savedMode==IJ.COMPOSITE) cImp.setMode(savedMode); cImp.setPosition(currentChannel, currentSlice, currentFrame); cImp.updateImage(); } protected void handlePopupMenu(MouseEvent e) { int x = e.getX(); int y = e.getY(); PopupMenu popup = new PopupMenu(); String[] colors = "Grays,-,Red,Green,Blue,Yellow,Magenta,Cyan,-,Fire,Ice,Spectrum,3-3-2 RGB,Red/Green".split(","); for (int jj = 0; jj < colors.length; jj++) { if (colors[jj].equals("-")) { popup.addSeparator(); } else { MenuItem mi = new MenuItem(colors[jj]); popup.add(mi); mi.addActionListener(this); } } add(popup); if (IJ.isMacOSX()) { IJ.wait(10); } popup.show(this, x, y); setCursor(defaultCursor); } public void actionPerformed(ActionEvent e) { String cmd = e.getActionCommand(); cImp.setPosition(currentChannel, currentSlice, currentFrame); CompositeImage cImp = (CompositeImage) this.cImp; IJ.run(cmd); repaint(); setCursor(defaultCursor); } public void mouseMoved(MouseEvent e) { int x = e.getX() - marginX; int y = e.getY() - marginY; if (x < 0 || x > nChannels * iconSize || y < 0 || y > iconSize * 2 + separatorY) { setCursor(defaultCursor); channelUnderCursor = 0; } else { int chn = x / iconSize + 1; if (y > iconSize) { if (chn <= seq.length()) { String digit = seq.substring(chn - 1, chn); chn = "1234567890".indexOf(digit) + 1; } else { chn = 0; } } if (y > 2 * iconSize + separatorY) { chn = 0; } channelUnderCursor = chn; } if (channelUnderCursor > 0) { setCursor(handCursor); } else { setCursor(defaultCursor); } } public void mouseEntered(MouseEvent e) { } public void mousePressed(MouseEvent e) { if (channelUnderCursor > 0) { currentChannel = channelUnderCursor; handlePopupMenu(e); repaint(); } } public void mouseReleased(MouseEvent e) { mouseMoved(e); } public void mouseExited(MouseEvent e) { } public void mouseDragged(MouseEvent e) { } public void mouseClicked(MouseEvent e) { } }

Ads help maintain this website.