private void singleGradient(int[] pixels, int w, int h, float rowrel, float dx, float dy) { int off = 0; for (int y = 0; y < h; y++) { float colrel = rowrel; int j = w; int rgb; if (colrel <= 0.0) { rgb = colormap.getColor(0); do { pixels[off] = PixelUtils.combinePixels(rgb, pixels[off], paintMode); off++; colrel += dx; } while (--j > 0 && colrel <= 0.0); } while (colrel < 1.0 && --j >= 0) { if (type == BILINEAR) rgb = colormap.getColor(map(ImageMath.triangle(colrel))); else rgb = colormap.getColor(map(colrel)); pixels[off] = PixelUtils.combinePixels(rgb, pixels[off], paintMode); off++; colrel += dx; } if (j > 0) { if (type == BILINEAR) rgb = colormap.getColor(0.0f); else rgb = colormap.getColor(1.0f); do { pixels[off] = PixelUtils.combinePixels(rgb, pixels[off], paintMode); off++; } while (--j > 0); } rowrel += dy; } }
/** Convolve with a 2D kernel */ public static void convolveHV( Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha, int edgeAction) { int index = 0; float[] matrix = kernel.getKernelData(null); int rows = kernel.getHeight(); int cols = kernel.getWidth(); int rows2 = rows / 2; int cols2 = cols / 2; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float r = 0, g = 0, b = 0, a = 0; for (int row = -rows2; row <= rows2; row++) { int iy = y + row; int ioffset; if (0 <= iy && iy < height) ioffset = iy * width; else if (edgeAction == CLAMP_EDGES) ioffset = y * width; else if (edgeAction == WRAP_EDGES) ioffset = ((iy + height) % height) * width; else continue; int moffset = cols * (row + rows2) + cols2; for (int col = -cols2; col <= cols2; col++) { float f = matrix[moffset + col]; if (f != 0) { int ix = x + col; if (!(0 <= ix && ix < width)) { if (edgeAction == CLAMP_EDGES) ix = x; else if (edgeAction == WRAP_EDGES) ix = (x + width) % width; else continue; } int rgb = inPixels[ioffset + ix]; a += f * ((rgb >> 24) & 0xff); r += f * ((rgb >> 16) & 0xff); g += f * ((rgb >> 8) & 0xff); b += f * (rgb & 0xff); } } } int ia = alpha ? PixelUtils.clamp((int) (a + 0.5)) : 0xff; int ir = PixelUtils.clamp((int) (r + 0.5)); int ig = PixelUtils.clamp((int) (g + 0.5)); int ib = PixelUtils.clamp((int) (b + 0.5)); outPixels[index++] = (ia << 24) | (ir << 16) | (ig << 8) | ib; } } }
/** Convolve with a kernel consisting of one column */ public static void convolveV( Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha, int edgeAction) { int index = 0; float[] matrix = kernel.getKernelData(null); int rows = kernel.getHeight(); int rows2 = rows / 2; for (int y = 0; y < height; y++) { for (int x = 0; x < width; x++) { float r = 0, g = 0, b = 0, a = 0; for (int row = -rows2; row <= rows2; row++) { int iy = y + row; int ioffset; if (iy < 0) { if (edgeAction == CLAMP_EDGES) ioffset = 0; else if (edgeAction == WRAP_EDGES) ioffset = ((y + height) % height) * width; else ioffset = iy * width; } else if (iy >= height) { if (edgeAction == CLAMP_EDGES) ioffset = (height - 1) * width; else if (edgeAction == WRAP_EDGES) ioffset = ((y + height) % height) * width; else ioffset = iy * width; } else ioffset = iy * width; float f = matrix[row + rows2]; if (f != 0) { int rgb = inPixels[ioffset + x]; a += f * ((rgb >> 24) & 0xff); r += f * ((rgb >> 16) & 0xff); g += f * ((rgb >> 8) & 0xff); b += f * (rgb & 0xff); } } int ia = alpha ? PixelUtils.clamp((int) (a + 0.5)) : 0xff; int ir = PixelUtils.clamp((int) (r + 0.5)); int ig = PixelUtils.clamp((int) (g + 0.5)); int ib = PixelUtils.clamp((int) (b + 0.5)); outPixels[index++] = (ia << 24) | (ir << 16) | (ig << 8) | ib; } } }
/** Convolve with a kernel consisting of one row */ public static void convolveH( Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha, int edgeAction) { int index = 0; float[] matrix = kernel.getKernelData(null); int cols = kernel.getWidth(); int cols2 = cols / 2; for (int y = 0; y < height; y++) { int ioffset = y * width; for (int x = 0; x < width; x++) { float r = 0, g = 0, b = 0, a = 0; int moffset = cols2; for (int col = -cols2; col <= cols2; col++) { float f = matrix[moffset + col]; if (f != 0) { int ix = x + col; if (ix < 0) { if (edgeAction == CLAMP_EDGES) ix = 0; else if (edgeAction == WRAP_EDGES) ix = (x + width) % width; } else if (ix >= width) { if (edgeAction == CLAMP_EDGES) ix = width - 1; else if (edgeAction == WRAP_EDGES) ix = (x + width) % width; } int rgb = inPixels[ioffset + ix]; a += f * ((rgb >> 24) & 0xff); r += f * ((rgb >> 16) & 0xff); g += f * ((rgb >> 8) & 0xff); b += f * (rgb & 0xff); } } int ia = alpha ? PixelUtils.clamp((int) (a + 0.5)) : 0xff; int ir = PixelUtils.clamp((int) (r + 0.5)); int ig = PixelUtils.clamp((int) (g + 0.5)); int ib = PixelUtils.clamp((int) (b + 0.5)); outPixels[index++] = (ia << 24) | (ir << 16) | (ig << 8) | ib; } } }
private void conicalGradient(int[] pixels, int y, int w, int h) { int off = 0; float angle0 = (float) Math.atan2(p2.x - p1.x, p2.y - p1.y); for (int x = 0; x < w; x++) { float angle = (float) (Math.atan2(x - p1.x, y - p1.y) - angle0) / (ImageMath.TWO_PI); angle += 1.0f; angle %= 1.0f; if (type == BICONICAL) angle = ImageMath.triangle(angle); int rgb = colormap.getColor(map(angle)); pixels[off] = PixelUtils.combinePixels(rgb, pixels[off], paintMode); off++; } }
private void squareGradient(int[] pixels, int y, int w, int h) { int off = 0; float radius = Math.max(Math.abs(p2.x - p1.x), Math.abs(p2.y - p1.y)); for (int x = 0; x < w; x++) { float distance = Math.max(Math.abs(x - p1.x), Math.abs(y - p1.y)); float ratio = distance / radius; if (repeat) ratio = ratio % 2; else if (ratio > 1.0) ratio = 1.0f; int rgb = colormap.getColor(map(ratio)); pixels[off] = PixelUtils.combinePixels(rgb, pixels[off], paintMode); off++; } }
private void repeatGradient(int[] pixels, int w, int h, float rowrel, float dx, float dy) { int off = 0; for (int y = 0; y < h; y++) { float colrel = rowrel; int j = w; int rgb; while (--j >= 0) { if (type == BILINEAR) rgb = colormap.getColor(map(ImageMath.triangle(colrel))); else rgb = colormap.getColor(map(ImageMath.mod(colrel, 1.0f))); pixels[off] = PixelUtils.combinePixels(rgb, pixels[off], paintMode); off++; colrel += dx; } rowrel += dy; } }
private int displacementMap(int x, int y) { return PixelUtils.clamp((int) (127 * (1 + Noise.noise2(x / xScale, y / xScale)))); }
/*
/** * Blur and transpose a block of ARGB pixels. * * @param kernel the blur kernel * @param inPixels the input pixels * @param outPixels the output pixels * @param width the width of the pixel array * @param height the height of the pixel array * @param alpha whether to blur the alpha channel * @param edgeAction what to do at the edges */ public static void convolveAndTranspose( Kernel kernel, int[] inPixels, int[] outPixels, int width, int height, boolean alpha, boolean premultiply, boolean unpremultiply, int edgeAction) { float[] matrix = kernel.getKernelData(null); int cols = kernel.getWidth(); int cols2 = cols / 2; for (int y = 0; y < height; y++) { int index = y; int ioffset = y * width; for (int x = 0; x < width; x++) { float r = 0, g = 0, b = 0, a = 0; int moffset = cols2; for (int col = -cols2; col <= cols2; col++) { float f = matrix[moffset + col]; if (f != 0) { int ix = x + col; if (ix < 0) { if (edgeAction == CLAMP_EDGES) ix = 0; else if (edgeAction == WRAP_EDGES) ix = (x + width) % width; } else if (ix >= width) { if (edgeAction == CLAMP_EDGES) ix = width - 1; else if (edgeAction == WRAP_EDGES) ix = (x + width) % width; } int rgb = inPixels[ioffset + ix]; int pa = (rgb >> 24) & 0xff; int pr = (rgb >> 16) & 0xff; int pg = (rgb >> 8) & 0xff; int pb = rgb & 0xff; if (premultiply) { float a255 = pa * (1.0f / 255.0f); pr *= a255; pg *= a255; pb *= a255; } a += f * pa; r += f * pr; g += f * pg; b += f * pb; } } if (unpremultiply && a != 0 && a != 255) { float f = 255.0f / a; r *= f; g *= f; b *= f; } int ia = alpha ? PixelUtils.clamp((int) (a + 0.5)) : 0xff; int ir = PixelUtils.clamp((int) (r + 0.5)); int ig = PixelUtils.clamp((int) (g + 0.5)); int ib = PixelUtils.clamp((int) (b + 0.5)); outPixels[index] = (ia << 24) | (ir << 16) | (ig << 8) | ib; index += height; } } }