package ddsutil; import java.awt.image.BufferedImage; import java.awt.image.Raster; import java.awt.image.WritableRaster; import java.nio.Buffer; import java.nio.BufferUnderflowException; import java.nio.ByteBuffer; import java.nio.IntBuffer; /** * General image functions for handling Images, BufferedImages and Arrays * @author danielsenff * */ public class ImageOperations { /** * Possible Display modes to select a specific channel. * So far only RGB is supported. */ public enum ChannelMode { /** * Display RGB with screen-overlayed Alpha-Channel. */ RGBA, /** * RGB without Alpha */ RGB, /** * Red color channel */ RED, /** * Green color channel */ GREEN, /** * Blue color channel */ BLUE, /** * Alpha color channel */ ALPHA } private ImageOperations() {} /** * Reads RGB colors from a single int color value. * @param c int with 3 colors included * @return int-array with RGB-values */ public static int[] readPixelRGB(final int c) { int[] color = { 255, (c & 0x00ff0000) >> 16, (c & 0x0000ff00) >> 8, (c & 0x000000ff)}; return color; } /** * Reads ARGB colors from a single int color value. * @param c int with 4 colors included * @return int-array with ARGB-values */ public static int[] readPixelARGB(final int c) { // this is dirty I think, I got the problem, that the a- value gets -1, instead of 255 // so I use this method to get a positive value instead ... int a = unsignedByteToInt((byte) ((c & 0xff000000) >> 24)); // System.out.println(a); // System.out.println((c & 0xff000000) >> 24); int[] color = { a, //a (c & 0x00ff0000) >> 16, //r (c & 0x0000ff00) >> 8, //g (c & 0x000000ff)}; //b return color; } /** * Write single color values into one int by byte-shifting. For RGB-pixelformat. * Returns an 32byte integer with 255 alpha * @param r * @param b * @param g * @return */ public static int writePixelRGB(final int r, final int g, final int b) { return 0xFF000000 + ((r & 0xff) << 16) + ((g & 0xff) << 8) + ( b & 0xff); } public static int writePixelRGB(final int[] color) { return writePixelRGB(color[0], color[1], color[2]); } /** * Write single color values into one int by byte-shifting. For ARGB-pixelsformat * @param a * @param r * @param b * @param g * @return */ public static int writePixelARGB(final int a, final int r, final int g, final int b) { return 0x00000000 + ((a & 0xff) << 24) + ((r & 0xff) << 16) + ((g & 0xff) << 8) + ( b & 0xff); } /** * @param color * @return */ public static int writePixelARGB(final int[] color) { return writePixelARGB(color[0], color[1], color[2], color[3]); } /** * Cast a Byte into an unsigned Integer * @param b * @return unsigned Integer */ public static int unsignedByteToInt(final byte b) { return (int) b & 0xFF; } /** * Paint Channel in a specified value (0-255) * Channel RGBA (0,1,2,3) * This is for {@link BufferedImage} * @param bi * @param channel * @param color * @return */ public static byte[] paintValueInChannel(final BufferedImage bi, final int channel, final float color) { return paintChannelInValue(ByteBufferedImage.convertBIintoARGBArray(bi), bi.getWidth(), bi.getHeight(), channel, color); } /** * Paint a specific RGB-color channel in a color * Channel RGBA (0,1,2,3) * This is for {@link ByteBuffer} * @param bytebuffer * @param width * @param height * @param channel * @param greyValue * @return */ public static byte[] paintValueInChannel(final ByteBuffer bytebuffer, final int width, final int height, final int channel, final float greyValue) { byte[] data = new byte[bytebuffer.capacity()]; bytebuffer.get(data); return paintChannelInValue(data, width, height, channel, greyValue); } /** * Paint Channel in a specified value (0-255) * Channel RGBA (0,1,2,3) * @param rgba * @param width * @param height * @param channel to paint in * @param color * @return */ public static byte[] paintChannelInValue(final byte[] rgba, final int width, final int height, final int channel, final float color) { int limit = width * height * 4; for (int pos = 0; pos < (limit)-3; pos = pos + 4) { rgba[pos + channel] = (byte) convertColor(color); } return rgba; } /** * Conversion between float color value to an integer value * @param value color * @return */ public static int convertColor(final float value) { return (int) (255*value); } /** * Conversion between double color value to a integer value * @param value color * @return */ public static int convertColor(final double value) { return (int) (255*value); } /** * Checks a color array if all values are within the possible range of values. * If the limits are exceeded, the value is set to equal the limit. * @param color * @param lowerLimit Upper limit of values * @param upperLimit Lower limit of values * @return */ public static int [] limitColorBoundaries(int[] color, final int lowerLimit, final int upperLimit) { for (int i = 0; i < color.length; i++) { color[i] = checkValueLimits(color[i], lowerLimit, upperLimit); } return color; } /** * Checks if the value is within defined limits. * @param value * @param lowerLimit * @param upperLimit * @return */ public static int checkValueLimits(int value, final int lowerLimit, final int upperLimit) { if (value < lowerLimit) { return lowerLimit; } else if (value > upperLimit) { return upperLimit; } else { return value; } } }