Inverting the colours of an Image means that we are subtracting colour of each pixel in that image from 255. As every pixel colour value ranges from 0 to 255 so total of 256 values, and we can change the value of any pixel as per our requirement. As this process is very slow and unsafe, most of the time, if we do any kind of mistake, it will crash your program. So you have to be very careful while implementing these methods, and must save all of your work before testing your code. In this article I will show you how can we edit colour of every pixel in an Image to change the look of Image.
You might be familiar with a very popular program Adobe Photoshop which is used for most of the Image Manipulations and Image creation projects. In that program as well you have a shortcut key to Invert colour of an image. The shortcut in Ctrl + I. Here are two images, first one is original image and 2nd one is after applying the Invert filter.
Now I will show you a code, which will do the same work done by Photoshop on that Image.
- First of all add a reference to following namespaces in your code.
- Now you have to load the Image in Bitmap class object, because we can apply any kind of manipulation on images using Bitmap Object.
Bitmap bitmap = (Bitmap)Bitmap.FromFile(pictureBox1.ImageLocation);
- Now we need a rectangle having width and height equal to width and height of the Image we loaded in bitmap. This rectangle will be used to carry all the pixels of Image in the memory.
Rectangle rectangle = new Rectangle(0, 0, bitmap.Width, bitmap.Height);
- Now we have to use BitmapData class to lock all the bits or pixels of the Image in memory. This is required because when we perform changes on our image, that image information must be available in memory. So that if by mistake we perform any wrong manipulation that won’t effect the Image directly and this process is faster as well as we have to perform manipulations on single byte at a time not the whole image in a single step.
BitmapData bitmapData =
- Now as our Image is in memory, so we have to use pointers to access all the bits of that Image from memory. Using the following line of code, our pointer will point to the starting bit of the Image in memory.
IntPtr ptr = bmpData.Scan0;
- Now we have to create byte array of size equal to the number of words in the image. Now what is word here??? If you just consider a single pixel, it constitute Red, Green and Blue values mixed together to give us a unique colour. Value for each of these colours(Red, Green, Blue) ranges from 0 to 255. Now a pixel constitute all the three values but in actual pixel further consist of three words one for each of these RGB colour. and in those words, value of Red, Green and Blue is stored. So in total we have three times words as compared to pixel. In some cases, there is some padding also applied on images, and in that section no colour information is available, but we are not considering that for now.
- We have Stride property of BitmapData object which will give us number of words present in a single line of pixel. and Height property of BitmapData object will give us the height of Image, actually it will give us the number of lines of pixels we have in our image. So if we multiply the two values we will be having number of words present in our Image. And then we can create an array of bytes of the calculated size.
int size = Math.Abs(bitmapData.Stride) * bitmap.Height;
byte rgbValues = new byte[size];
- Now we need to copy all the words values to this bytes array using the pointer we already created which is pointing to the starting bit of the image. For this we will use Marshal class.
Marshal.Copy(ptr, rgbValues, 0, size);
- Now we have colour information of every pixel or word of that image in this bytes array. So for Inverting Colours, all we have to do is subtract the value of every byte from 255 and then store the result again in that byte.
for (int i = 0; i < rgbValues.Length; i++)
rgbValues[i] = Convert.ToByte(255 - rgbValues[i]);
- Now our bytes array have all the bytes with manipulated colour information. Now we have to copy back all these bytes information to the memory using Marshal class again.
Marshal.Copy(rgbValues, 0, ptr, size);
- Now we have to unlock the bits from memory and then our Bitmap object will be having manipulated Image which we can show in a Picture Box or save in our hard disk.
pictureBox1.Image = bitmap;
Here is the output of the same image I have used in Photoshop to explain Invert Function. Just have a look at the two images one after applying Invert Filter in Photoshop and one after applying manipulation using C# code. These two images are totally same.