Adding or subtracting color from an image in a pictureBox using C#

后端 未结 1 1641
情话喂你
情话喂你 2020-11-28 16:59

I\'d like to learn how to code some very basic image editing in Visual Studio. I\'m using the openFileDialog to load a picture into a pictureBox. I\'ve found some loops on

相关标签:
1条回答
  • 2020-11-28 17:26

    This is an example of using Getpixel and SetPixel.

    For (much much) faster filter results look into Lockbits and also into using a ColorMatrix

    private void button2_Click(object sender, EventArgs e)
    {
        // we pull the bitmap from the image
        Bitmap bmp = (Bitmap) pictureBox1.Image;
    
        // we change some picels
        for (int y = 100; y < bmp.Height; y++) 
        for (int x = 100; x < bmp.Width; x++)
        {
            Color c = bmp.GetPixel(x, y);
            bmp.SetPixel(x, y, Color.FromArgb(255, 255, c.G, c.B));
        }
        // we need to re-assign the changed bitmap
        pictureBox1.Image = (Bitmap) bmp;
    }
    

    enter image description hereenter image description here

    Update:

    The code above is a very simple introduction. It is simple but also very slow and it is not very flexible.

    Here is a version that is both very fast and and much more flexible:

    private void button3_Click(object sender, EventArgs e)
    {
        // pick one of our filter methods
        ModifyHue hueChanger = new ModifyHue(MaxChannel);
    
        // we pull the bitmap from the image
        Bitmap bmp = (Bitmap)pictureBox1.Image;
        Size s = bmp.Size;
        PixelFormat fmt = bmp.PixelFormat;
        // we need the bit depth and we assume either 32bppArgb or 24bppRgb !
        byte bpp = (byte)(fmt == PixelFormat.Format32bppArgb ? 4 : 3);
        // lock the bits and prepare the loop
        Rectangle rect = new Rectangle(Point.Empty, s);
        BitmapData bmpData = bmp.LockBits(rect, ImageLockMode.ReadOnly, fmt);
        int size1 = bmpData.Stride * bmpData.Height;
        byte[] data = new byte[size1];
        System.Runtime.InteropServices.Marshal.Copy(bmpData.Scan0, data, 0, size1);
        // loops
        for (int y = 0; y < s.Height; y++)
        {
            for (int x = 0; x < s.Width; x++)
            {
                // calculate the index
                int index = y * bmpData.Stride + x * bpp;
                // get the color
                Color c = Color.FromArgb( bpp == 4 ?data[index + 3]: 255 , 
                                          data[index + 2], data[index + 1], data[index]);
                // process it
                c = hueChanger(c, 2); 
                // set the channels from the new color
                data[index + 0] = c.B;
                data[index + 1] = c.G;
                data[index + 2] = c.R;
                if (bpp == 4) data[index + 3] = c.A;
            }
        }
    
        System.Runtime.InteropServices.Marshal.Copy(data, 0, bmpData.Scan0, data.Length);
        bmp.UnlockBits(bmpData);
    
       // we need to re-assign the changed bitmap
        pictureBox1.Image = (Bitmap)bmp;
    }
    

    The above code calls a delegate:

    public delegate Color ModifyHue(Color c, int ch);
    

    And the delegate is set to call a simple filter function:

    public Color MaxChannel(Color c, int channel)
    {
        if (channel == 1) return Color.FromArgb(255, 255, c.G, c.B);
        if (channel == 2) return Color.FromArgb(255, c.R, 255, c.B);
        if (channel == 3) return Color.FromArgb(255, c.R, c.G, 255);
        else return c;
    }
    

    And here is another one that changes a Color to grey

    public Color ToGreyscale(Color c, int dummy)
    {
        byte val = (byte) ( (c.R * 0.299f + c.G * 0.587f + c.B *0.114f)  ) ;
        return Color.FromArgb(255, val, val,val);
    }
    

    Note that all methods we want to call via a delegate need to have the same signature. Therefore ToGreyscale also takes an integer as second parameter, even though it doesn't use it..

    Also note that you can limit the LockBits loop start and end values just like in the simple example before to get the second screenshot..

    0 讨论(0)
提交回复
热议问题