@Override public void applyInPlace(FastBitmap fastBitmap) { if (fastBitmap.isRGB()) { int size = fastBitmap.getWidth() * fastBitmap.getHeight(); for (int i = 0; i < size; i++) { int r = fastBitmap.getRed(i); int g = fastBitmap.getGreen(i); int b = fastBitmap.getBlue(i); float[] color = ColorConverter.RGBtoHLS(r, g, b); int[] newColor = ColorConverter.HSLtoRGB(degree, color[1], color[2]); newColor[0] = newColor[0] > 255 ? 255 : newColor[0]; newColor[0] = newColor[0] < 0 ? 0 : newColor[0]; newColor[1] = newColor[1] > 255 ? 255 : newColor[1]; newColor[1] = newColor[1] < 0 ? 0 : newColor[1]; newColor[2] = newColor[2] > 255 ? 255 : newColor[2]; newColor[2] = newColor[2] < 0 ? 0 : newColor[2]; fastBitmap.setRGB(i, newColor); } } else { throw new IllegalArgumentException("Hue modifier only works in RGB images."); } }
/** * Extract blob. * * @param id ID. * @param fastBitmap Image to be processed. * @return Image with the extracted blob. */ public FastBitmap Extract(int id, FastBitmap fastBitmap) { // Check if blobs list is null. if (this.blobs == null) this.blobs = new BlobDetection().ProcessImage(fastBitmap); FastBitmap image; if (fastBitmap.isGrayscale()) { image = new FastBitmap( fastBitmap.getWidth(), fastBitmap.getHeight(), FastBitmap.ColorSpace.Grayscale); for (IntPoint p : blobs.get(id).getPoints()) { image.setGray(p.x, p.y, fastBitmap.getGray(p.x, p.y)); } } else { image = new FastBitmap(fastBitmap.getWidth(), fastBitmap.getHeight(), FastBitmap.ColorSpace.RGB); for (IntPoint p : blobs.get(id).getPoints()) { image.setRed(p.x, p.y, fastBitmap.getRed(p.x, p.y)); image.setGreen(p.x, p.y, fastBitmap.getGreen(p.x, p.y)); image.setBlue(p.x, p.y, fastBitmap.getBlue(p.x, p.y)); } } return image; }
@Override public void applyInPlace(FastBitmap fastBitmap) { int size = fastBitmap.getSize(); if (fastBitmap.isGrayscale()) { CalculateMap(inGray, outGray, mapGray); for (int x = 0; x < size; x++) { fastBitmap.setGray(x, mapGray[fastBitmap.getGray(x)]); } } else { CalculateMap(inRed, outRed, mapRed); CalculateMap(inGreen, outGreen, mapGreen); CalculateMap(inBlue, outBlue, mapBlue); for (int x = 0; x < size; x++) { int r = mapRed[fastBitmap.getRed(x)]; int g = mapGreen[fastBitmap.getGreen(x)]; int b = mapBlue[fastBitmap.getBlue(x)]; fastBitmap.setRGB(x, r, g, b); } } }
/** * Computes histograms. * * @param fastBitmap Image. */ private void ProcessImage(FastBitmap fastBitmap) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); if (fastBitmap.isGrayscale()) { int[] g = new int[width]; for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { g[y] += fastBitmap.getGray(x, y); } } gray = new Histogram(g); } if (fastBitmap.isRGB()) { int[] r = new int[width]; int[] g = new int[width]; int[] b = new int[width]; for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { r[y] += fastBitmap.getRed(x, y); g[y] += fastBitmap.getGreen(x, y); b[y] += fastBitmap.getBlue(x, y); } } red = new Histogram(r); green = new Histogram(g); blue = new Histogram(b); } }
@Override public void applyInPlace(FastBitmap fastBitmap) { if (fastBitmap.isRGB() && overlay.isRGB()) { int w = fastBitmap.getWidth(); int h = fastBitmap.getHeight(); switch (algorithm) { case Lighten: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { if (overlay.getRed(i, j) > fastBitmap.getRed(i, j)) { fastBitmap.setRed(i, j, overlay.getRed(i, j)); } if (overlay.getGreen(i, j) > fastBitmap.getGreen(i, j)) { fastBitmap.setGreen(i, j, overlay.getGreen(i, j)); } if (overlay.getBlue(i, j) > fastBitmap.getBlue(i, j)) { fastBitmap.setBlue(i, j, overlay.getBlue(i, j)); } } } break; case Darken: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { if (overlay.getRed(i, j) < fastBitmap.getRed(i, j)) { fastBitmap.setRed(i, j, overlay.getRed(i, j)); } if (overlay.getGreen(i, j) < fastBitmap.getGreen(i, j)) { fastBitmap.setGreen(i, j, overlay.getGreen(i, j)); } if (overlay.getBlue(i, j) < fastBitmap.getBlue(i, j)) { fastBitmap.setBlue(i, j, overlay.getBlue(i, j)); } } } break; case Multiply: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int r = fastBitmap.getRed(i, j) * overlay.getRed(i, j) / 255; int g = fastBitmap.getGreen(i, j) * overlay.getGreen(i, j) / 255; int b = fastBitmap.getBlue(i, j) * overlay.getBlue(i, j) / 255; fastBitmap.setRGB(i, j, r, g, b); } } break; case Average: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int r = fastBitmap.getRed(i, j) + overlay.getRed(i, j) / 2; int g = fastBitmap.getGreen(i, j) + overlay.getGreen(i, j) / 2; int b = fastBitmap.getBlue(i, j) + overlay.getBlue(i, j) / 2; fastBitmap.setRGB(i, j, r, g, b); } } break; case Add: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int r = Math.min(fastBitmap.getRed(i, j) + overlay.getRed(i, j), 255); int g = Math.min(fastBitmap.getGreen(i, j) + overlay.getGreen(i, j), 255); int b = Math.min(fastBitmap.getBlue(i, j) + overlay.getBlue(i, j), 255); fastBitmap.setRGB(i, j, r, g, b); } } break; case Subtract: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int temp = fastBitmap.getRed(i, j) + overlay.getRed(i, j); if (temp < 255) { fastBitmap.setRed(i, j, 0); } else { fastBitmap.setRed(i, j, temp - 255); } temp = fastBitmap.getGreen(i, j) + overlay.getGreen(i, j); if (temp < 255) { fastBitmap.setGreen(i, j, 0); } else { fastBitmap.setGreen(i, j, temp - 255); } temp = fastBitmap.getBlue(i, j) + overlay.getBlue(i, j); if (temp < 255) { fastBitmap.setBlue(i, j, 0); } else { fastBitmap.setBlue(i, j, temp - 255); } } } break; case Difference: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int r = Math.abs(fastBitmap.getRed(i, j) - overlay.getRed(i, j)); int g = Math.abs(fastBitmap.getGreen(i, j) - overlay.getGreen(i, j)); int b = Math.abs(fastBitmap.getBlue(i, j) - overlay.getBlue(i, j)); fastBitmap.setRGB(i, j, r, g, b); } } break; case Negation: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int r = 255 - Math.abs(255 - fastBitmap.getRed(i, j) - overlay.getRed(i, j)); int g = 255 - Math.abs(255 - fastBitmap.getGreen(i, j) - overlay.getGreen(i, j)); int b = 255 - Math.abs(255 - fastBitmap.getBlue(i, j) - overlay.getBlue(i, j)); fastBitmap.setRGB(i, j, r, g, b); } } break; case Screen: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int r = ((255 - (((255 - fastBitmap.getRed(i, j)) * (255 - overlay.getRed(i, j))) >> 8))); int g = ((255 - (((255 - fastBitmap.getGreen(i, j)) * (255 - overlay.getGreen(i, j))) >> 8))); int b = ((255 - (((255 - fastBitmap.getBlue(i, j)) * (255 - overlay.getBlue(i, j))) >> 8))); fastBitmap.setRGB(i, j, r, g, b); } } break; case Exclusion: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int r = ((fastBitmap.getRed(i, j) + overlay.getRed(i, j) - 2 * fastBitmap.getRed(i, j) * overlay.getRed(i, j) / 255)); int g = ((fastBitmap.getGreen(i, j) + overlay.getGreen(i, j) - 2 * fastBitmap.getGreen(i, j) * overlay.getGreen(i, j) / 255)); int b = ((fastBitmap.getBlue(i, j) + overlay.getBlue(i, j) - 2 * fastBitmap.getBlue(i, j) * overlay.getBlue(i, j) / 255)); fastBitmap.setRGB(i, j, r, g, b); } } break; case Overlay: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int temp; if (overlay.getRed(i, j) < 128) { temp = (2 * fastBitmap.getRed(i, j) * overlay.getRed(i, j) / 255); temp = Math.min(255, temp); fastBitmap.setRed(i, j, temp); } else { temp = (255 - 2 * (255 - fastBitmap.getRed(i, j)) * (255 - overlay.getRed(i, j)) / 255); temp = Math.min(255, temp); fastBitmap.setRed(i, j, temp); } if (overlay.getGreen(i, j) < 128) { temp = (2 * fastBitmap.getGreen(i, j) * overlay.getGreen(i, j) / 255); temp = Math.min(255, temp); fastBitmap.setGreen(i, j, temp); } else { temp = (255 - 2 * (255 - fastBitmap.getGreen(i, j)) * (255 - overlay.getGreen(i, j)) / 255); temp = Math.min(255, temp); fastBitmap.setGreen(i, j, temp); } if (overlay.getBlue(i, j) < 128) { temp = (2 * fastBitmap.getBlue(i, j) * overlay.getBlue(i, j) / 255); temp = Math.min(255, temp); fastBitmap.setBlue(i, j, temp); } else { temp = (255 - 2 * (255 - fastBitmap.getBlue(i, j)) * (255 - overlay.getBlue(i, j)) / 255); temp = Math.min(255, temp); fastBitmap.setBlue(i, j, temp); } } } break; case SoftLight: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int temp; if (fastBitmap.getRed(i, j) < 128) { temp = (2 * overlay.getRed(i, j) * fastBitmap.getRed(i, j) / 255); temp = Math.min(255, temp); fastBitmap.setRed(i, j, temp); } else { temp = (255 - 2 * (255 - overlay.getRed(i, j)) * (255 - fastBitmap.getRed(i, j)) / 255); temp = Math.min(255, temp); overlay.setRed(i, j, temp); } if (fastBitmap.getGreen(i, j) < 128) { temp = (2 * overlay.getGreen(i, j) * fastBitmap.getGreen(i, j) / 255); temp = Math.min(255, temp); fastBitmap.setGreen(i, j, temp); } else { temp = (255 - 2 * (255 - overlay.getGreen(i, j)) * (255 - fastBitmap.getGreen(i, j)) / 255); temp = Math.min(255, temp); fastBitmap.setGreen(i, j, temp); } if (fastBitmap.getBlue(i, j) < 128) { temp = (2 * overlay.getBlue(i, j) * fastBitmap.getBlue(i, j) / 255); temp = Math.min(255, temp); fastBitmap.setBlue(i, j, temp); } else { temp = (255 - 2 * (255 - overlay.getBlue(i, j)) * (255 - fastBitmap.getBlue(i, j)) / 255); temp = Math.min(255, temp); fastBitmap.setBlue(i, j, temp); } } } break; case HardLight: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { float temp; if (overlay.getRed(i, j) < 128) { temp = (2 * ((fastBitmap.getRed(i, j) >> 1) + 64)) * ((float) overlay.getRed(i, j) / 255); fastBitmap.setRed(i, j, (int) temp); } else { temp = (255 - (2 * (255 - ((fastBitmap.getRed(i, j) >> 1) + 64)) * (float) (255 - overlay.getRed(i, j)) / 255)); fastBitmap.setRed(i, j, (int) temp); } if (overlay.getGreen(i, j) < 128) { temp = (2 * ((fastBitmap.getGreen(i, j) >> 1) + 64)) * ((float) overlay.getGreen(i, j) / 255); fastBitmap.setGreen(i, j, (int) temp); } else { temp = (255 - (2 * (255 - ((fastBitmap.getGreen(i, j) >> 1) + 64)) * (float) (255 - overlay.getGreen(i, j)) / 255)); fastBitmap.setGreen(i, j, (int) temp); } if (overlay.getBlue(i, j) < 128) { temp = (2 * ((fastBitmap.getBlue(i, j) >> 1) + 64)) * ((float) overlay.getBlue(i, j) / 255); fastBitmap.setBlue(i, j, (int) temp); } else { temp = (255 - (2 * (255 - ((fastBitmap.getBlue(i, j) >> 1) + 64)) * (float) (255 - overlay.getBlue(i, j)) / 255)); fastBitmap.setBlue(i, j, (int) temp); } } } break; case ColorDodge: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { if (overlay.getRed(i, j) == 255) { fastBitmap.setRed(i, j, 255); } else { int x = Math.min(255, ((fastBitmap.getRed(i, j) << 8) / (255 - overlay.getRed(i, j)))); fastBitmap.setRed(i, j, x); } if (overlay.getGreen(i, j) == 255) { fastBitmap.setGreen(i, j, 255); } else { int x = Math.min( 255, ((fastBitmap.getGreen(i, j) << 8) / (255 - overlay.getGreen(i, j)))); fastBitmap.setGreen(i, j, x); } if (overlay.getBlue(i, j) == 255) { fastBitmap.setBlue(i, j, 255); } else { int x = Math.min( 255, ((fastBitmap.getBlue(i, j) << 8) / (255 - overlay.getBlue(i, j)))); fastBitmap.setBlue(i, j, x); } } } break; case ColorBurn: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { if (overlay.getRed(i, j) == 0) { fastBitmap.setRed(i, j, overlay.getRed(i, j)); } else { int x = Math.max( 0, (255 - ((255 - fastBitmap.getRed(i, j)) << 8) / overlay.getRed(i, j))); fastBitmap.setRed(i, j, x); } if (overlay.getGreen(i, j) == 0) { fastBitmap.setGreen(i, j, overlay.getGreen(i, j)); } else { int x = Math.max( 0, (255 - ((255 - fastBitmap.getGreen(i, j)) << 8) / overlay.getGreen(i, j))); fastBitmap.setGreen(i, j, x); } if (overlay.getBlue(i, j) == 0) { fastBitmap.setBlue(i, j, overlay.getBlue(i, j)); } else { int x = Math.max( 0, (255 - ((255 - fastBitmap.getBlue(i, j)) << 8) / overlay.getBlue(i, j))); fastBitmap.setBlue(i, j, x); } } } break; case LinearLight: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int temp; if (overlay.getRed(i, j) < 128) { temp = fastBitmap.getRed(i, j) + (2 * overlay.getRed(i, j)); if (temp < 255) { fastBitmap.setRed(i, j, 0); } else { fastBitmap.setRed(i, j, (temp - 255)); } } else { int x = Math.min(fastBitmap.getRed(i, j) + (2 * (overlay.getRed(i, j) - 128)), 255); fastBitmap.setRed(i, j, x); } if (overlay.getGreen(i, j) < 128) { temp = fastBitmap.getGreen(i, j) + (2 * overlay.getGreen(i, j)); if (temp < 255) { fastBitmap.setGreen(i, j, 0); } else { fastBitmap.setGreen(i, j, (temp - 255)); } } else { int x = Math.min(fastBitmap.getGreen(i, j) + (2 * (overlay.getGreen(i, j) - 128)), 255); fastBitmap.setGreen(i, j, x); } if (overlay.getBlue(i, j) < 128) { temp = fastBitmap.getBlue(i, j) + (2 * overlay.getBlue(i, j)); if (temp < 255) { fastBitmap.setBlue(i, j, 0); } else { fastBitmap.setBlue(i, j, (temp - 255)); } } else { int x = Math.min(fastBitmap.getBlue(i, j) + (2 * (overlay.getBlue(i, j) - 128)), 255); fastBitmap.setBlue(i, j, x); } } } break; case VividLight: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { if (overlay.getRed(i, j) < 128) { // Color Burn int o = overlay.getRed(i, j) * 2; if (o == 0) { fastBitmap.setRed(i, j, o); } else { int x = Math.max(0, (255 - ((255 - fastBitmap.getRed(i, j)) << 8) / o)); fastBitmap.setRed(i, j, x); } } else { // Color Dodge int o = 2 * (overlay.getRed(i, j) - 128); if (o == 255) { fastBitmap.setRed(i, j, 255); } else { int x = Math.min(255, ((fastBitmap.getRed(i, j) << 8) / (255 - o))); fastBitmap.setRed(i, j, x); } } if (overlay.getGreen(i, j) < 128) { // Color Burn int o = overlay.getGreen(i, j) * 2; if (o == 0) { fastBitmap.setGreen(i, j, o); } else { int x = Math.max(0, (255 - ((255 - fastBitmap.getGreen(i, j)) << 8) / o)); fastBitmap.setGreen(i, j, x); } } else { // Color Dodge int o = 2 * (overlay.getGreen(i, j) - 128); if (o == 255) { fastBitmap.setGreen(i, j, 255); } else { int x = Math.min(255, ((fastBitmap.getGreen(i, j) << 8) / (255 - o))); fastBitmap.setGreen(i, j, x); } } if (overlay.getBlue(i, j) < 128) { // Color Burn int o = overlay.getBlue(i, j) * 2; if (o == 0) { fastBitmap.setBlue(i, j, o); } else { int x = Math.max(0, (255 - ((255 - fastBitmap.getBlue(i, j)) << 8) / o)); fastBitmap.setBlue(i, j, x); } } else { // Color Dodge int o = 2 * (overlay.getBlue(i, j) - 128); if (o == 255) { fastBitmap.setGreen(i, j, 255); } else { int x = Math.min(255, ((fastBitmap.getBlue(i, j) << 8) / (255 - o))); fastBitmap.setBlue(i, j, x); } } } } break; case PinLight: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int o = overlay.getRed(i, j) * 2; if (overlay.getRed(i, j) < 128) { // Darken if (o < fastBitmap.getRed(i, j)) { fastBitmap.setRed(i, j, o); } } else { // Lighten if (o > fastBitmap.getRed(i, j)) { fastBitmap.setRed(i, j, o); } } o = overlay.getGreen(i, j) * 2; if (overlay.getGreen(i, j) < 128) { // Darken if (o < fastBitmap.getGreen(i, j)) { fastBitmap.setGreen(i, j, o); } } else { // Lighten if (o > fastBitmap.getGreen(i, j)) { fastBitmap.setGreen(i, j, o); } } o = overlay.getBlue(i, j) * 2; if (overlay.getBlue(i, j) < 128) { // Darken if (o < fastBitmap.getBlue(i, j)) { fastBitmap.setBlue(i, j, o); } } else { // Lighten if (o > fastBitmap.getBlue(i, j)) { fastBitmap.setBlue(i, j, o); } } } } break; case Reflect: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { if (overlay.getRed(i, j) == 255) { fastBitmap.setRed(i, j, 255); } else { int x = Math.min( 255, (fastBitmap.getRed(i, j) * fastBitmap.getRed(i, j) / (255 - overlay.getRed(i, j)))); fastBitmap.setRed(i, j, x); } if (overlay.getGreen(i, j) == 255) { fastBitmap.setGreen(i, j, 255); } else { int x = Math.min( 255, (fastBitmap.getGreen(i, j) * fastBitmap.getGreen(i, j) / (255 - overlay.getGreen(i, j)))); fastBitmap.setGreen(i, j, x); } if (overlay.getBlue(i, j) == 255) { fastBitmap.setBlue(i, j, 255); } else { int x = Math.min( 255, (fastBitmap.getBlue(i, j) * fastBitmap.getBlue(i, j) / (255 - overlay.getBlue(i, j)))); fastBitmap.setBlue(i, j, x); } } } break; case Phoenix: for (int i = 0; i < h; i++) { for (int j = 0; j < w; j++) { int r = ((Math.min(fastBitmap.getRed(i, j), overlay.getRed(i, j)) - Math.max(fastBitmap.getRed(i, j), overlay.getRed(i, j)) + 255)); int g = ((Math.min(fastBitmap.getGreen(i, j), overlay.getGreen(i, j)) - Math.max(fastBitmap.getGreen(i, j), overlay.getGreen(i, j)) + 255)); int b = ((Math.min(fastBitmap.getBlue(i, j), overlay.getBlue(i, j)) - Math.max(fastBitmap.getBlue(i, j), overlay.getBlue(i, j)) + 255)); fastBitmap.setRGB(i, j, r, g, b); } } break; } } else { throw new IllegalArgumentException("Blend only works in RGB images."); } }
@Override public void applyInPlace(FastBitmap fastBitmap) { if (fastBitmap.isGrayscale()) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); double oldIradius = (double) (height - 1) / 2; double oldJradius = (double) (width - 1) / 2; CalculateNewSize(fastBitmap); FastBitmap destinationData = new FastBitmap(newWidth, newHeight, FastBitmap.ColorSpace.Grayscale); // get destination image size double newIradius = (double) (newHeight - 1) / 2; double newJradius = (double) (newWidth - 1) / 2; // angle's sine and cosine double angleRad = -angle * Math.PI / 180; double angleCos = Math.cos(angleRad); double angleSin = Math.sin(angleRad); // destination pixel's coordinate relative to image center double ci, cj; // coordinates of source points and cooefficiens double oi, oj, di, dj, k1, k2; int oi1, oj1, oi2, oj2; // width and height decreased by 1 int imax = height - 1; int jmax = width - 1; ci = -newIradius; for (int i = 0; i < newHeight; i++) { cj = -newJradius; for (int j = 0; j < newWidth; j++) { // coordinate of the nearest point oi = angleCos * ci + angleSin * cj + oldIradius; oj = -angleSin * ci + angleCos * cj + oldJradius; oi1 = (int) oi; oj1 = (int) oj; // validate source pixel's coordinates if ((oi1 < 0) || (oj1 < 0) || (oi1 >= height) || (oj1 >= width)) { // fill destination image with filler destinationData.setGray(i, j, fillGray); } else { di = oi - (double) oi1; dj = oj - (double) oj1; // initial pixel value int g = 0; for (int n = -1; n < 3; n++) { // get Y cooefficient k1 = Interpolation.BiCubicKernel(dj - (double) n); oj2 = oj1 + n; if (oj2 < 0) oj2 = 0; if (oj2 > jmax) oj2 = jmax; for (int m = -1; m < 3; m++) { // get X cooefficient k2 = k1 * Interpolation.BiCubicKernel((double) m - di); oi2 = oi1 + m; if (oi2 < 0) oi2 = 0; if (oi2 > imax) oi2 = imax; g += k2 * fastBitmap.getGray(oi2, oj2); } } destinationData.setGray(i, j, Math.max(0, Math.min(255, g))); } cj++; } ci++; } fastBitmap.setImage(destinationData); destinationData.recycle(); } else if (fastBitmap.isRGB()) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); double oldIradius = (double) (height - 1) / 2; double oldJradius = (double) (width - 1) / 2; CalculateNewSize(fastBitmap); FastBitmap destinationData = new FastBitmap(newWidth, newHeight, FastBitmap.ColorSpace.RGB); // get destination image size double newIradius = (double) (newHeight - 1) / 2; double newJradius = (double) (newWidth - 1) / 2; // angle's sine and cosine double angleRad = -angle * Math.PI / 180; double angleCos = Math.cos(angleRad); double angleSin = Math.sin(angleRad); // destination pixel's coordinate relative to image center double ci, cj; // coordinates of source points and cooefficiens double oi, oj, di, dj, k1, k2; int oi1, oj1, oi2, oj2; // width and height decreased by 1 int imax = height - 1; int jmax = width - 1; ci = -newIradius; for (int i = 0; i < newHeight; i++) { cj = -newJradius; for (int j = 0; j < newWidth; j++) { // coordinate of the nearest point oi = angleCos * ci + angleSin * cj + oldIradius; oj = -angleSin * ci + angleCos * cj + oldJradius; oi1 = (int) oi; oj1 = (int) oj; // validate source pixel's coordinates if ((oi < 0) || (oj < 0) || (oi >= height) || (oj >= width)) { // fill destination image with filler destinationData.setRGB(i, j, fillRed, fillGreen, fillBlue); } else { di = oi - (double) oi1; dj = oj - (double) oj1; // initial pixel value int r = 0; int g = 0; int b = 0; for (int n = -1; n < 3; n++) { // get Y cooefficient k1 = Interpolation.BiCubicKernel(dj - (double) n); oj2 = oj1 + n; if (oj2 < 0) oj2 = 0; if (oj2 > jmax) oj2 = jmax; for (int m = -1; m < 3; m++) { // get X cooefficient k2 = k1 * Interpolation.BiCubicKernel((double) m - di); oi2 = oi1 + m; if (oi2 < 0) oi2 = 0; if (oi2 > imax) oi2 = imax; r += k2 * fastBitmap.getRed(oi2, oj2); g += k2 * fastBitmap.getGreen(oi2, oj2); b += k2 * fastBitmap.getBlue(oi2, oj2); } } r = Math.max(0, Math.min(255, r)); g = Math.max(0, Math.min(255, g)); b = Math.max(0, Math.min(255, b)); destinationData.setRGB(i, j, r, g, b); } cj++; } ci++; } fastBitmap.setImage(destinationData); destinationData.recycle(); } }
@Override public void applyInPlace(FastBitmap fastBitmap) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); int Xline, Yline; int lines = CalcLines(radius); int maxArray = lines * lines; int c; FastBitmap copy = new FastBitmap(fastBitmap); if (fastBitmap.isGrayscale()) { int[] avgL = new int[maxArray]; for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { c = 0; for (int i = 0; i < lines; i++) { Xline = x + (i - radius); for (int j = 0; j < lines; j++) { Yline = y + (j - radius); if ((Xline >= 0) && (Xline < height) && (Yline >= 0) && (Yline < width)) { avgL[c] = copy.getGray(Xline, Yline); } else { avgL[c] = copy.getGray(x, y); } c++; } } Arrays.sort(avgL); // alpha trimmed mean double mean = 0; for (int i = t; i < c - t; i++) { mean += avgL[i]; } fastBitmap.setGray(x, y, (int) (mean / (avgL.length - 2 * t))); } } } else if (fastBitmap.isRGB()) { int[] avgR = new int[maxArray]; int[] avgG = new int[maxArray]; int[] avgB = new int[maxArray]; for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { c = 0; for (int i = 0; i < lines; i++) { Xline = x + (i - radius); for (int j = 0; j < lines; j++) { Yline = y + (j - radius); if ((Xline >= 0) && (Xline < height) && (Yline >= 0) && (Yline < width)) { avgR[c] = copy.getRed(Xline, Yline); avgG[c] = copy.getGreen(Xline, Yline); avgB[c] = copy.getBlue(Xline, Yline); } else { avgR[c] = copy.getRed(x, y); avgG[c] = copy.getGreen(x, y); avgB[c] = copy.getBlue(x, y); } c++; } } Arrays.sort(avgR); Arrays.sort(avgG); Arrays.sort(avgB); // alpha trimmed mean double meanR = 0, meanG = 0, meanB = 0; for (int i = t; i < c - t; i++) { meanR += avgR[i]; meanG += avgG[i]; meanB += avgB[i]; } meanR /= (avgR.length - 2 * t); meanG /= (avgG.length - 2 * t); meanB /= (avgB.length - 2 * t); fastBitmap.setRGB(x, y, (int) meanR, (int) meanG, (int) meanB); } } } }
@Override public void applyInPlace(FastBitmap fastBitmap) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); int Xline, Yline; int radiusI = (weight.length - 1) / 2; int radiusJ = (weight[0].length - 1) / 2; int maxArray = calcMax(weight); int c; FastBitmap copy = new FastBitmap(fastBitmap); if (fastBitmap.isGrayscale()) { int[] avgL = new int[maxArray]; int median; for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { c = 0; for (int i = 0; i < weight.length; i++) { Xline = x + (i - radiusI); for (int j = 0; j < weight[0].length; j++) { Yline = y + (j - radiusJ); if ((Xline >= 0) && (Xline < height) && (Yline >= 0) && (Yline < width)) { if (weight[i][j] > 0) { for (int k = 0; k < weight[i][j]; k++) { avgL[c] = copy.getGray(Xline, Yline); c++; } } } } } Arrays.sort(avgL, 0, c); // median median = c / 2; fastBitmap.setGray(x, y, avgL[median]); } } } else if (fastBitmap.isRGB()) { int[] avgR = new int[maxArray]; int[] avgG = new int[maxArray]; int[] avgB = new int[maxArray]; int median; for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { c = 0; for (int i = 0; i < weight.length; i++) { Xline = x + (i - radiusI); for (int j = 0; j < weight[0].length; j++) { Yline = y + (j - radiusJ); if ((Xline >= 0) && (Xline < height) && (Yline >= 0) && (Yline < width)) { if (weight[i][j] > 0) { for (int k = 0; k < weight[i][j]; k++) { avgR[c] = copy.getRed(Xline, Yline); avgG[c] = copy.getGreen(Xline, Yline); avgB[c] = copy.getBlue(Xline, Yline); c++; } } } } } Arrays.sort(avgR, 0, c); Arrays.sort(avgG, 0, c); Arrays.sort(avgB, 0, c); // median median = c / 2; fastBitmap.setRGB(x, y, avgR[median], avgG[median], avgB[median]); } } } }
@Override public void applyInPlace(FastBitmap fastBitmap) { int width = fastBitmap.getWidth(); int height = fastBitmap.getHeight(); FastBitmap copy = new FastBitmap(fastBitmap); if (fastBitmap.isGrayscale()) { for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { double mean = 0; double var = 0; int total = 0; for (int i = x - radius; i <= x + radius; i++) { for (int j = y - radius; j <= y + radius; j++) { if (i >= 0 && i < height && j >= 0 && j < width) { mean += copy.getGray(i, j); total++; } } } mean /= total; for (int i = x - radius; i <= x + radius; i++) { for (int j = y - radius; j <= y + radius; j++) { if (i >= 0 && i < height && j >= 0 && j < width) var += Math.pow(copy.getGray(i, j) - mean, 2); } } var /= total - 1; if (var < 0) var = 0; if (var > 255) var = 255; fastBitmap.setGray(x, y, (int) var); } } } if (fastBitmap.isRGB()) { for (int x = 0; x < height; x++) { for (int y = 0; y < width; y++) { double meanR = 0, meanG = 0, meanB = 0; double varR = 0, varG = 0, varB = 0; int total = 0; for (int i = x - radius; i <= x + radius; i++) { for (int j = y - radius; j <= y + radius; j++) { if (i >= 0 && i < height && j >= 0 && j < width) { meanR += copy.getRed(i, j); meanG += copy.getGreen(i, j); meanB += copy.getBlue(i, j); total++; } } } meanR /= total; meanG /= total; meanB /= total; for (int i = x - radius; i <= x + radius; i++) { for (int j = y - radius; j <= y + radius; j++) { if (i >= 0 && i < height && j >= 0 && j < width) { varR += Math.pow(copy.getRed(i, j) - meanR, 2); varG += Math.pow(copy.getGreen(i, j) - meanG, 2); varB += Math.pow(copy.getBlue(i, j) - meanB, 2); } } } varR /= total - 1; varG /= total - 1; varB /= total - 1; if (varR < 0) varR = 0; if (varG < 0) varG = 0; if (varB < 0) varB = 0; if (varR > 255) varR = 255; if (varG > 255) varG = 255; if (varB > 255) varB = 255; fastBitmap.setRGB(x, y, (int) varR, (int) varG, (int) varB); } } } }