/** * Scale the RGB channels for a color by a fixed amount. * * This is useful for brightening/darkening an input color. * * @param rgb * @param scale * @return */ public static int makeScaledRGB(final int rgb, final double scale) { return makeRGB( (int)Math.min(255, (ColorTools.red(rgb)*scale)), (int)Math.min(255, (ColorTools.green(rgb)*scale)), (int)Math.min(255, (ColorTools.blue(rgb)*scale))); }
/** * Create a 'normalized' color by converting RGB values to optical densities, putting the RGB ODs into * a 3x1 vector and normalizing this to unit length, then rescaling the result to give an RGB representation. * Because of the somewhat strange rescaling involved, the final RGB values produced should not be over-interpreted - * this is really intended for visualization, such as when interactively looking for regions of single stains * when selecting color deconvolution stain vectors. * * @param rgb original 8-bit RGB values * @param minOD the minimum OD - pixels with an OD less than this will be considered unstained, and shown as white * @param offset brightness and contrast offset * @param scale brightness and contrast scale value * @return normalized color, as packed RGB value */ public static int getODNormalizedColor(int rgb, double minOD, float offset, float scale) { double r_od = od_lut[ColorTools.red(rgb)]; double g_od = od_lut[ColorTools.green(rgb)]; double b_od = od_lut[ColorTools.blue(rgb)]; double norm = Math.sqrt(r_od*r_od + g_od*g_od + b_od*b_od); if (norm < minOD) { norm = minOD; //Jreturn ((255<<16) + (255<<8) + 255) & ~ColorTools.MASK_ALPHA | (rgb & ColorTools.MASK_ALPHA); return 0x00ffffff | (rgb & ColorTools.MASK_ALPHA); //J Slightly faster? } int r = 255-ColorTools.do8BitRangeCheck((255*r_od/norm - offset) * scale); int g = 255-ColorTools.do8BitRangeCheck((255*g_od/norm - offset) * scale); int b = 255-ColorTools.do8BitRangeCheck((255*b_od/norm - offset) * scale); return ((r<<16) + (g<<8) + b) & ~ColorTools.MASK_ALPHA | (rgb & ColorTools.MASK_ALPHA); }
/** * Create a new packed-int representation of an RGB color. * * @param v A value between 0 and 255. If a single value is give, the result will be * a shade of gray (RGB all with that value). Otherwise, 3 or 4 values may be given to generate * either an RGB or RGBA color. * @return */ public static Integer getColorRGB(final int... v) { if (v.length == 1) return ColorTools.makeRGB(v[0], v[0], v[0]); if (v.length == 3) return ColorTools.makeRGB(v[0], v[1], v[2]); if (v.length == 4) return ColorTools.makeRGBA(v[0], v[1], v[2], v[3]); throw new IllegalArgumentException("Input to getColorRGB must be either 1, 3 or 4 integer values, between 0 and 255!"); }
/** * Method that may be used to get RGB colors. * Classes that only provide RGB images may call this from their getDefaultChannelColors method. * * @param channel * @return */ protected Integer getDefaultRGBChannelColors(int channel) { if (nChannels() == 1) return ColorTools.makeRGB(255, 255, 255); switch (channel) { case 0: return ColorTools.makeRGB(255, 0, 0); case 1: return ColorTools.makeRGB(0, 255, 0); case 2: return ColorTools.makeRGB(0, 0, 255); default: return ColorTools.makeRGB(255, 255, 255); } }
public void setLUTColor(int r, int g, int b) { // Create a LUT rgbLUT = new int[256]; byte[] rb = new byte[256]; byte[] gb = new byte[256]; byte[] bb = new byte[256]; for (int i = 0; i < 256; i++) { rgbLUT[i] = ColorTools.makeRGB( ColorTools.do8BitRangeCheck(r / 255.0 * i), ColorTools.do8BitRangeCheck(g / 255.0 * i), ColorTools.do8BitRangeCheck(b / 255.0 * i) ); rb[i] = (byte)ColorTools.do8BitRangeCheck(r / 255.0 * i); gb[i] = (byte)ColorTools.do8BitRangeCheck(g / 255.0 * i); bb[i] = (byte)ColorTools.do8BitRangeCheck(b / 255.0 * i); } cm = new IndexColorModel(8, 256, rb, gb, bb); this.rgb = (r << 16) + (g << 8) + b; // this.r = do8BitRangeCheck(r); // this.g = do8BitRangeCheck(g); // this.b = do8BitRangeCheck(b); // this.rgb = (r << 16) + (g << 8) + b; }
/** * Get a scaled version of the specified color, where the RGB values are independently scaled by a specified factor. * * The alpha value is preserved unchanged. * * @param color * @return */ public static Color scaleColor(Color color, double factor) { return new Color(ColorTools.do8BitRangeCheck(color.getRed()*factor), ColorTools.do8BitRangeCheck(color.getGreen()*factor), ColorTools.do8BitRangeCheck(color.getBlue()*factor), color.getAlpha()); }
/** * Convert red channel of packed rgb pixel to optical density values, using a specified maximum value. * * @param rgb * @param maxValue * @param px optional array used for output * @return */ public static float[] getGreenOpticalDensities(int[] rgb, double maxValue, float[] px) { if (px == null) px = new float[rgb.length]; double[] od_lut = makeODLUT(maxValue, 256); for (int i = 0; i < px.length; i++) px[i] = (float)makeODByLUT(ColorTools.green(rgb[i]), od_lut); return px; }
/** * Convert red channel of packed rgb pixel to optical density values, using a specified maximum value. * * @param rgb * @param maxValue * @param px optional array used for output * @return */ public static float[] getBlueOpticalDensities(int[] rgb, double maxValue, float[] px) { if (px == null) px = new float[rgb.length]; double[] od_lut = makeODLUT(maxValue, 256); for (int i = 0; i < px.length; i++) px[i] = (float)makeODByLUT(ColorTools.blue(rgb[i]), od_lut); return px; }
/** * Convert red channel of packed rgb pixel to optical density values, using a specified maximum value. * * @param rgb * @param maxValue * @param px optional array used for output * @return */ public static float[] getRedOpticalDensities(int[] rgb, double maxValue, float[] px) { if (px == null) px = new float[rgb.length]; double[] od_lut = makeODLUT(maxValue, 256); for (int i = 0; i < px.length; i++) px[i] = (float)makeODByLUT(ColorTools.red(rgb[i]), od_lut); return px; }
/** * Get a Color object, possibly from a shared map (used to avoid creating too many objects unnecessarily). * @param r * @param g * @param b * @param a * @return */ public static Color getCachedColor(final int r, final int g, final int b, final int a) { return ColorToolsAwt.getCachedColor(ColorTools.makeRGBA(r, g, b, a)); }
/** * Get cached color. Assumed not to have alpha set, unless the relevant bits are non-zero. * @param rgb * @return */ public static Color getCachedColor(final Integer rgb) { return getCachedColor(rgb, ColorTools.alpha(rgb.intValue()) > 0); }
/** * Similar to getDefaultRGBChannelColors, but including Magenta, Cyan & Yellow to return colors for up to 6 channels. * If only one channel is present, or a channel number > 6 is requested, Color.WHITE is returned. * * @param channel * @return */ protected Integer getExtendedDefaultChannelColor(int channel) { if (nChannels() == 1) return ColorTools.makeRGB(255, 255, 255); switch (channel) { case 0: return ColorTools.makeRGB(255, 0, 0); case 1: return ColorTools.makeRGB(0, 255, 0); case 2: return ColorTools.makeRGB(0, 0, 255); case 3: return ColorTools.makeRGB(255, 255, 0); case 4: return ColorTools.makeRGB(0, 255, 255); case 5: return ColorTools.makeRGB(255, 255, 0); default: return ColorTools.makeRGB(255, 255, 255); } }
public static int deconvolve8bit(int rgb, double[][] invMat, double[] od_lut_red, double[] od_lut_green, double[] od_lut_blue, int stain) { // Apply deconvolution & store the results return ColorTools.do8BitRangeCheck(Math.exp(-deconvolve(rgb, invMat, od_lut_red, od_lut_green, od_lut_blue, stain)) * 255); }
/** * Get a color with a specified opacity, based on the packed RGB values in an Integer. * * @param rgb * @param opacity * @return */ public static Color getColorWithOpacity(Integer rgb, double opacity) { if (rgb == null) return null; if (opacity > 1) opacity = 1; else if (opacity < 0) opacity = 0; // IJ.log("Opacity: " + (int)(opacity * 255 + .5)); return new Color(ColorTools.red(rgb), ColorTools.green(rgb), ColorTools.blue(rgb), (int)(opacity * 255 + .5)); }
int ind = 0; for (int v : buffer) { int r = ColorTools.do8BitRangeCheck((ColorTools.red(v) - offset) * scale); int g = ColorTools.do8BitRangeCheck((ColorTools.green(v) - offset) * scale); int b = ColorTools.do8BitRangeCheck((ColorTools.blue(v) - offset) * scale); rgb[ind] = (r << 16) + (g << 8) + b; ind++;
/** * Determine median of RGB values. * The median of each channel is computed separately. * * @param name * @param rgb * @param redMax * @param greenMax * @param blueMax * @return */ public static int getMedianRGB(int[] rgb) { int n = rgb.length; // Extract medians for each channel int[] temp = new int[n]; for (int i = 0; i < rgb.length; i++) temp[i] = ColorTools.red(rgb[i]); int rMedian = getMedian(temp); for (int i = 0; i < rgb.length; i++) temp[i] = ColorTools.green(rgb[i]); int gMedian = getMedian(temp); for (int i = 0; i < rgb.length; i++) temp[i] = ColorTools.blue(rgb[i]); int bMedian = getMedian(temp); return ColorTools.makeRGB(rMedian, gMedian, bMedian); }
/** * Get a Color object, possibly from a shared map (used to avoid creating too many objects unnecessarily). * @param r * @param g * @param b * @return */ public static Color getCachedColor(final int r, final int g, final int b) { return ColorToolsAwt.getCachedColor(ColorTools.makeRGB(r, g, b)); }
public static int deconvolve8bit(int rgb, double[][] invMat, double[] od_lut, int stain) { // Apply deconvolution & store the results return ColorTools.do8BitRangeCheck(Math.exp(-deconvolve(rgb, invMat, od_lut, stain)) * 255); }