package io.swtc.proccessing; import java.util.stream.IntStream; public class DenoiseProccessor { public int[] process(int[] srcPixels, int width, int height, float strength) { if (strength <= 0) return srcPixels; int[] dstPixels = new int[srcPixels.length]; int[] tempPixels = new int[srcPixels.length]; int radius = (int) (strength / 100f * 2) + 1; // Pass 1: Horizontal IntStream.range(0, height).parallel().forEach(y -> blurLine(srcPixels, tempPixels, width, height, y, radius, true) ); // Pass 2: Vertical IntStream.range(0, width).parallel().forEach(x -> blurLine(tempPixels, dstPixels, width, height, x, radius, false) ); return dstPixels; } private void blurLine(int[] src, int[] dest, int w, int h, int lineIndex, int radius, boolean horizontal) { int length = horizontal ? w : h; int limit = length - 1; for (int i = 0; i < length; i++) { long rSum = 0, gSum = 0, bSum = 0; int count = 0; int start = Math.max(0, i - radius); int end = Math.min(limit, i + radius); for (int k = start; k <= end; k++) { int idx = horizontal ? (lineIndex * w + k) : (k * w + lineIndex); int rgb = src[idx]; rSum += (rgb >> 16) & 0xFF; gSum += (rgb >> 8) & 0xFF; bSum += rgb & 0xFF; count++; } int targetIdx = horizontal ? (lineIndex * w + i) : (i * w + lineIndex); dest[targetIdx] = ((int)(rSum/count) << 16) | ((int)(gSum/count) << 8) | (int)(bSum/count); } } }