Хороший способ и с хорошей производительностью - использовать функцию LockBits для доступа к данным изображения, используя LockBits, вы можете создавать растровое изображение с использованием каждого байта изображения, lockBit блокирует данные изображения в памяти для изменения данных каждого пикселя изображения растрового изображения. Смотрите пример:
Bitmap bm = new Bitmap(512, 512);
BitmapData bmd=bm.LockBits(new Rectangle(0, 0, 10, 10), System.Drawing.Imaging.ImageLockMode.ReadOnly, bm.PixelFormat);
int PixelSize=4;
for(int y=0; y<bmd.Height; y++)
{
byte* row=(byte *)bmd.Scan0+(y*bmd.Stride);
for(int x=0; x<bmd.Width; x++)
{
// Here you change your pixel data
row[x*PixelSize]=255;
}
}
bm.UnlockBits(bmd)
рисовать в PictureBox вы можете просто сцепить член Изображение PictureBox, или сделать из вручную путем. Смотрите следующие примеры:
// concatenate
pict1.Image = bmp;
или
// Draw using CreateGraphics
Graphics g = Graphics.FromHwnd(pictureBox1.Handle);
g.DrawImage(bmp, new Point(10, 10));
О оттенках серого можно получить оттенки серого цвета только с использованием значения одного канала изображения или получить среднее значение между значениями RGB и использовать то же самое значение для эти три канала, см этот пример:
// Average value between channels
Color oc = bmp.GetPixel(i, x);
int grayScale = (int)((oc.R * 0.3) + (oc.G * 0.59) + (oc.B * 0.11));
Color nc = Color.FromArgb(oc.A, grayScale, grayScale, grayScale);
d.SetPixel(x, y, nc); // if you are using bitmap
или
// value from one channel
Color pixelColor = c.GetPixel(x, y);
Color newColor = Color.FromArgb(pixelColor.R, pixelColor.R, pixelColor.R);
c.SetPixel(x, y, newColor); // Now greyscale
Подробнее о LockBits в этой ссылке: http://bobpowell.net/lockingbits.aspx
и о оттенках серых: http://en.wikipedia.org/wiki/Grayscale