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;
}