internal ColorRaw Compute(ColorRaw[] data) { float r = 0; float g = 0; float b = 0; for (int i = 0; i < _filter.Length; ++i) { r += _filter[i] * data[i].R; g += _filter[i] * data[i].G; b += _filter[i] * data[i].B; } r = r / _factor + _offset; g = g / _factor + _offset; b = b / _factor + _offset; return(ColorRaw.FromRgb(Clamp(r), Clamp(g), Clamp(b))); }
// Helpers! // ReSharper disable once SuggestBaseTypeForParameter private static void ComputeEdgeDetectFilter0AtOffsetNapron(deviceptr <ColorRaw> input, deviceptr <ColorRaw> result, int resultLength, float[] mFilter, float mFactor, float mOffset, int i, int width) { var cx = i % width; var cy = i / width; var sx = cx - 1; var sy = cy - 1; var ex = cx + 1; var ey = cy + 1; var r = 0f; var g = 0f; var b = 0f; var filterIndex = 0; for (var y = sy; y <= ey; ++y) { for (var x = sx; x <= ex; ++x) { var offset = y * width + x; var pixel = offset < resultLength ? input[offset] : ColorRaw.FromRgb(0, 0, 0); var currentFilter = mFilter[filterIndex++]; r += pixel.R * currentFilter; g += pixel.G * currentFilter; b += pixel.B * currentFilter; } } r = r / mFactor + mOffset; g = g / mFactor + mOffset; b = b / mFactor + mOffset; result[i] = ColorRaw.FromRgb(Clamp(r), Clamp(g), Clamp(b)); }
internal static ColorRaw[] ToColorArray(Bitmap bmp) { var result = new ColorRaw[bmp.Width * bmp.Height]; var temp = new byte[Marshal.SizeOf <ColorRaw>() * bmp.Width * bmp.Height]; var data = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.ReadOnly, DefaultPixelFormat); Marshal.Copy(data.Scan0, temp, 0, temp.Length); bmp.UnlockBits(data); Parallel.For(0, result.Length, i => { var k = 3 * i; result[i] = new ColorRaw { R = temp[k + 0], G = temp[k + 1], B = temp[k + 2], }; }); return(result); }
// Custom Array! internal static Image Render2(Bitmap image, ConvolutionFilter filter) { var width = image.Width; var height = image.Height; var source = BitmapUtility.ToColorArray(image); var result = new ColorRaw[width * height]; Parallel.For(0, height, y => { for (var x = 0; x < width; ++x) { var offset = y * width + x; var neighbours = GetNeighbours(x, y, width, height, (nx, ny, i) => (nx >= 0 && nx < width && ny >= 0 && ny < height) == false ? ColorRaw.FromRgb(0, 0, 0) : source[i]); result[offset] = filter.Compute(neighbours); } }); return(BitmapUtility.FromColorArray(result, image.Width, image.Height)); }