/** * @author Pacien TRAN-GIRARD * @author Timothée FLOURE */ public final class Color { public static final int BYTE_MASK = 0b11111111; public static final float DECIMAL_NORMALIZER = 255.0f; public static final int RED_SHIFT = 16; public static final int GREEN_SHIFT = 8; public static final int BLUE_SHIFT = 0; /** * Returns shifted component from given packed color. * * @param rgb 32-bits RGB color * @param shift binary shift * @return a float between 0.0 and 1.0 * @see #getRGBValue */ private static float getNormalizedRGBComponent(int rgb, int shift) { return ((float) (rgb >> shift & BYTE_MASK)) / DECIMAL_NORMALIZER; } /** * Returns RGB binary value from given component and color shift. * * @param component a float between 0.0 and 1.0 * @param shift binary shift * @return 32-bits RGB color * @see #getNormalizedRGBComponent */ private static int getRGBValue(float component, int shift) { if (component < 0.0f) component = 0.0f; if (component > 1.0f) component = 1.0f; return ((int) (component * DECIMAL_NORMALIZER) & BYTE_MASK) << shift; } /** * Returns red component from given packed color. * * @param rgb 32-bits RGB color * @return a float between 0.0 and 1.0 * @see #getGreen * @see #getBlue * @see #getRGB(float, float, float) */ public static float getRed(int rgb) { return Color.getNormalizedRGBComponent(rgb, RED_SHIFT); } /** * Returns green component from given packed color. * * @param rgb 32-bits RGB color * @return a float between 0.0 and 1.0 * @see #getRed * @see #getBlue * @see #getRGB(float, float, float) */ public static float getGreen(int rgb) { return Color.getNormalizedRGBComponent(rgb, GREEN_SHIFT); } /** * Returns blue component from given packed color. * * @param rgb 32-bits RGB color * @return a float between 0.0 and 1.0 * @see #getRed * @see #getGreen * @see #getRGB(float, float, float) */ public static float getBlue(int rgb) { return Color.getNormalizedRGBComponent(rgb, BLUE_SHIFT); } /** * Returns the average of red, green and blue components from given packed color. * * @param rgb 32-bits RGB color * @return a float between 0.0 and 1.0 * @see #getRed * @see #getGreen * @see #getBlue * @see #getRGB(float) */ public static float getGray(int rgb) { return (Color.getRed(rgb) + Color.getGreen(rgb) + Color.getBlue(rgb)) / 3.0f; } /** * Returns packed RGB components from given red, green and blue components. * * @param red a float between 0.0 and 1.0 * @param green a float between 0.0 and 1.0 * @param blue a float between 0.0 and 1.0 * @return 32-bits RGB color * @see #getRed * @see #getGreen * @see #getBlue */ public static int getRGB(float red, float green, float blue) { int rgbValue = 0b0; rgbValue |= Color.getRGBValue(red, RED_SHIFT); rgbValue |= Color.getRGBValue(green, GREEN_SHIFT); rgbValue |= Color.getRGBValue(blue, BLUE_SHIFT); return rgbValue; } /** * Returns packed RGB components from given grayscale value. * * @param gray a float between 0.0 and 1.0 * @return 32-bits RGB color * @see #getGray */ public static int getRGB(float gray) { return Color.getRGB(gray, gray, gray); } /** * Converts packed RGB image to grayscale float image. * * @param image a HxW int array * @return a HxW float array * @see #toRGB * @see #getGray */ public static float[][] toGray(int[][] image) { int width = image[0].length; int height = image.length; float[][] floatImage = new float[height][width]; for (int row = 0; row < height; ++row) for (int col = 0; col < width; ++col) floatImage[row][col] = Color.getGray(image[row][col]); return floatImage; } /** * Converts grayscale float image to packed RGB image. * * @param gray a HxW float array * @return a HxW int array * @see #toGray * @see #getRGB(float) */ public static int[][] toRGB(float[][] gray) { int width = gray[0].length; int height = gray.length; int[][] rgbImage = new int[height][width]; for (int row = 0; row < height; ++row) for (int col = 0; col < width; ++col) rgbImage[row][col] = Color.getRGB(gray[row][col]); return rgbImage; } }