public static Bitmap Additive(Bitmap image, Rectangle region, int amount) { int startX = region.Left; int startY = region.Top; int stopX = image.Width - 1; int stopY = image.Height - 1; if (startX + region.Width < image.Width) { stopX = startX + region.Width; } if (startY + region.Height < image.Height) { stopY = startX + region.Height; } Bitmap b = new Bitmap(image); BitmapData bmpData = b.LockBits(new Rectangle(0, 0, b.Width, b.Height), ImageLockMode.ReadWrite, b.PixelFormat); IntPtr ptr = bmpData.Scan0; int stride = bmpData.Stride; int bytes = Math.Abs(bmpData.Stride) * b.Height; byte[] rgbValues = new byte[bytes]; System.Runtime.InteropServices.Marshal.Copy(ptr, rgbValues, 0, bytes); IRandomNumberGenerator generator = new UniformGenerator(new Range(-amount, amount)); Parallel.For(startY, stopY, y => { for (int x = startX; x < stopX; x++) { int i = y * stride + x * 4; rgbValues[i] = (byte)Math.Max(0, Math.Min(255, rgbValues[i] + generator.Next())); rgbValues[i + 1] = (byte)Math.Max(0, Math.Min(255, rgbValues[i + 1] + generator.Next())); rgbValues[i + 2] = (byte)Math.Max(0, Math.Min(255, rgbValues[i + 2] + generator.Next())); } }); System.Runtime.InteropServices.Marshal.Copy(rgbValues, 0, ptr, bytes); b.UnlockBits(bmpData); return b; }