I was bored and messing around with C# tonight. This isn't anything serious, but just the same I ran into a problem and don't have the answer.

The idea was to be able to edit the contents of a bitmap as if it was a List<Color>. This code is supposed to convert my PictureBox image to greyscale, but about 25% of the image to the right comes out completely black, and the rest of the image is partially desaturated, but still retains a bit of color and has noticeable vertical striping.

Code:
private void button1_Click(object sender, EventArgs e)
{
    PixelImage img = new PixelImage((Bitmap)pBox1.Image);

    var pixels = new List<Color>();

    img.Pixels.ForEach((pixel) => { pixels.Add(GreyScale(pixel)); });

    img.Pixels = pixels;
    pBox1.Image = img.Bitmap;
}

private Color GreyScale(Color color)
{
    int grey = (int)(color.R * 0.299 + color.G * 0.587 + color.B * 0.114);
    return Color.FromArgb(255, grey, grey, grey);
}


public class PixelImage
{
    public PixelImage(Bitmap image) { img = image; }
    public PixelImage(int Width, int Height) { img = new Bitmap(Width, Height); }
    public Bitmap Bitmap { get { return img; } set { img = value; } }

    public unsafe List<Color> Pixels
    {
        get
        {
            var pixels = new List<Color>();

            BitmapData data = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppRgb);

            for (int y = 0; y < img.Height; y++)
            {
                byte* ptr = (byte*)data.Scan0 + (y * data.Stride);
                for (int x = 0; x < img.Width; x++)
                {
                    byte B = ptr[x * 3];
                    byte G = ptr[x * 3 + 1];
                    byte R = ptr[x * 3 + 2];
                    pixels.Add(Color.FromArgb(255, R, G, B));
                }
            }

            img.UnlockBits(data);
            return pixels;
        }

        set
        {
            List<Color> pixels = value;

            BitmapData data = img.LockBits(new Rectangle(0, 0, img.Width, img.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppRgb);

            for (int y = 0; y < img.Height; y++)
            {
                byte* ptr = (byte*)data.Scan0 + (y * data.Stride);
                for (int x = 0; x < img.Width; x++)
                {
                    ptr[x * 3] = pixels[y * img.Width + x].B;
                    ptr[x * 3 + 1] = pixels[y * img.Width + x].G;
                    ptr[x * 3 + 2] = pixels[y * img.Width + x].R;
                }
            }

            img.UnlockBits(data);
        }
    }

    private Bitmap img;
}