/* * RgbSelectGray.java * * Created on August 27, 2006, 11:33 AM * * To change this template, choose Tools | Template Manager * and open the template in the editor. * * Copyright 2007 by Jon A. Webb * This program is free software: you can redistribute it and/or modify * it under the terms of the GNU Lesser General Public License as published by * the Free Software Foundation, either version 3 of the License, or * (at your option) any later version. * * This program is distributed in the hope that it will be useful, * but WITHOUT ANY WARRANTY; without even the implied warranty of * MERCHANTABILITY or FITNESS FOR A PARTICULAR PURPOSE. See the * GNU Lesser General Public License for more details. * * You should have received a copy of the Lesser GNU General Public License * along with this program. If not, see <http://www.gnu.org/licenses/>. * */ package jjil.algorithm; import jjil.core.Error; import jjil.core.Gray8Image; import jjil.core.Image; import jjil.core.PipelineStage; import jjil.core.RgbImage; import jjil.core.RgbVal; /** * <p> * Transforms a RgbImage into a Gray8Image by selecting one of the three * bands. The pixel value chosen is adjusted from the range 0→255 to the * range -128→127. * </p> * <p> * Usage: <br> * * <CODE> * RgbImage imageRgb = ...;<br> * RgbSelectGray rgb = new RgbSelectGray(RgbSelectGray.RED);<br> * rgb.push(imageRgb); * </CODE> * </p> * @author webb */ public class RgbSelectGray extends PipelineStage { /* In the absence of enums in version 1.3 we use three empty singleton * classes to represent the color choice. */ /** * Used to represent the three colors red, green, or blue. */ public static class ColorClass { private String name; private static final ColorClass RED = new ColorClass("RED"); private static final ColorClass GREEN = new ColorClass("GREEN"); private static final ColorClass BLUE = new ColorClass("BLUE"); private ColorClass(String name) { this.name = name; } /** * Represents the color red. * @return A ColorClass object that represents the color red. */ public static ColorClass Red() { return RED; } /** * Represents the color green. * @return A ColorClass object that represents the color green. */ public static ColorClass Green() { return GREEN; } /** * Represents the color blue. * @return A ColorClass object that represents the color blue. */ public static ColorClass Blue() { return BLUE; } /** * Returns a string representation of the RgbSelectGray operation. * @return a String representing the RgbSelectGray operation. */ public String toString() { return name; } }; /** * The class represents the color red. It is used like an enumerated value when * calling the RgbSelectGray constructor. */ public static final ColorClass RED = ColorClass.Red(); /** * The class represents the color green. It is used like an enumerated value when * calling the RgbSelectGray constructor. */ public static final ColorClass GREEN = ColorClass.Green(); /** * The class represents the color blue. It is used like an enumerated value when * calling the RgbSelectGray constructor. */ public static final ColorClass BLUE = ColorClass.Blue(); /** * Aliases for red, green, and blue used when we're thinking of the RGB image * as an HSV image. */ public static final ColorClass HUE = ColorClass.Red(); public static final ColorClass SATURATION = ColorClass.Green(); public static final ColorClass VALUE = ColorClass.Blue(); private ColorClass colorChosen; /** * Creates a new instance of RgbSelectGray. * @param color the color selected from the color image to create the gray image. * @throws jjil.core.Error if color is not RED, GREEN, or BLUE. */ public RgbSelectGray(ColorClass color) throws jjil.core.Error { setColor(color); } /** * Returns the current color selected. * * @return the current color, as a ColorClass object. */ public ColorClass getColor() { return this.colorChosen; } /** Convert a color image to gray by selecting one of the color * bands: red, green, or blue. The band selected is chosen in the * class constructor. The gray pixel value is adjusted so its range * is from -128→127 instead of the 0-255 value in the ARGB word. * * @param image the input image * @throws jjil.core.Error if the input image is not a color * image. */ public void push(Image image) throws jjil.core.Error { if (!(image instanceof RgbImage)) { throw new Error( Error.PACKAGE.ALGORITHM, ErrorCodes.IMAGE_NOT_RGBIMAGE, image.toString(), null, null); } RgbImage rgb = (RgbImage) image; int[] rgbData = rgb.getData(); Gray8Image gray = new Gray8Image(image.getWidth(), image.getHeight()); byte[] grayData = gray.getData(); if (colorChosen.equals(RED)) { for (int i=0; i<image.getWidth() * image.getHeight(); i++) { /* get individual color value, unmasking it from the * ARGB word */ grayData[i] = RgbVal.getR(rgbData[i]); } } else if (this.colorChosen.equals(GREEN)) { for (int i=0; i<image.getWidth() * image.getHeight(); i++) { /* get individual color value, unmasking it from the * ARGB word */ grayData[i] = RgbVal.getG(rgbData[i]); } } else /* must be BLUE, from constructor */ { for (int i=0; i<image.getWidth() * image.getHeight(); i++) { /* get individual color value, unmasking it from the * ARGB word */ grayData[i] = RgbVal.getB(rgbData[i]); } } super.setOutput(gray); } /** * Changes the color selected. * @param color the new color selected * @throws jjil.core.Error if the input color is not ColorClass.RED, GREEN, or BLUE. */ public void setColor(ColorClass color) throws jjil.core.Error { /* as I understand the language this can't happen, but just in * case... */ if (!(color.equals(RgbSelectGray.RED) || color.equals(RgbSelectGray.GREEN) || color.equals(RgbSelectGray.BLUE))) { throw new Error( Error.PACKAGE.ALGORITHM, ErrorCodes.ILLEGAL_COLOR_CHOICE, color.toString(), null, null); } this.colorChosen = color; } /** Return a string describing the RGB select operation. * * @return the string describing the RGB select operation. */ public String toString() { return super.toString() + " (" + this.colorChosen.toString() + //$NON-NLS-1$ ")"; //$NON-NLS-1$ } }