Article Purpose
The focus of this article is set on exploring the concept of Image Solarisation. In this article the tasks required to perform Image Solarisation are entirely implemented on pixel data level. Image manipulation is only implemented in the form of updating the individual Alpha, Red, Green and Blue colour components expressed by Image pixels.
Sample source code
This article is accompanied by a sample source code Visual Studio project which is available for download here.
What is Image Solarisation?
Image Solarisation can be described as a form of Image inversion/colour inversion. A distinction can be made between solarisation and colour inversion when taking into regard threshold values implemented when performing image solarisation.
Colour inversion can be implemented by subtracting each colour component from the value 255 and then assigning the relevant colour component to the result of subtraction. Colour inversion in terms of a formula can be expressed as follows:
R = 255 – R1
G = 255 – G1
B = 255 – B1
In this expression R1 G2 and B1 represent the original value of a pixel’s Red, Green and Blue colour components prior to being updated. Image Solarisation when expressed as a formula could be represented as follows:
R = R1
If R1 < RT Then R = 255 – R1
G = G1
If G1 < GT Then G = 255 – G1
B = B1
If B1 < BT Then B = 255 – B1
When implementing this expression R1 G1 and B1 represent the original value of a pixel’s Red, Green and Blue colour components prior to being updated. RT GT and BT in this scenario represent configurable threshold values applicable to individual colour components. If a colour component’s original value equates to less than the corresponding threshold value only then should colour inversion be implemented.
Using the sample Application
The concepts discussed in this article are implemented/tested by means of a Windows Forms application. When using the sample application a user has the ability to browse the local file system in order to specify a source/input image. The user interface includes three trackbar controls, each related to a colour component threshold value. Threshold values can range from 0 to 255 inclusive. A threshold value of 0 results in no change, whereas a value of 255 equates to regular colour inversion.
Updated/filtered images can be saved to the local file system at any stage by clicking the ‘Save Image’ button.
The following image is a screenshot of the Image Solarise sample application in action:
The Solarise Extension Method
The sample source code provides the definition for the Solarise extension method. The method has been defined as an extension method targeting the Bitmap class.
The following code snippet details the implementation of the Solarise extension method:
public static Bitmap Solarise(this Bitmap sourceBitmap, byte blueValue, byte greenValue, byte redValue) { BitmapData sourceData = sourceBitmap.LockBits(new Rectangle (0, 0, sourceBitmap.Width, sourceBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
byte[] pixelBuffer = new byte[sourceData.Stride * sourceData.Height];
Marshal.Copy(sourceData.Scan0, pixelBuffer, 0, pixelBuffer.Length);
sourceBitmap.UnlockBits(sourceData);
byte byte255 = 255;
for (int k = 0; k + 4 < pixelBuffer.Length; k += 4) { if (pixelBuffer[k] < blueValue) { pixelBuffer[k] = (byte)(byte255 - pixelBuffer[k]); }
if (pixelBuffer[k + 1] < greenValue) { pixelBuffer[k + 1] = (byte)(byte255 - pixelBuffer[k + 1]); }
if (pixelBuffer[k + 2] < redValue) { pixelBuffer[k + 2] = (byte)(byte255 - pixelBuffer[k + 2]); } }
Bitmap resultBitmap = new Bitmap(sourceBitmap.Width, sourceBitmap.Height); BitmapData resultData = resultBitmap.LockBits(new Rectangle (0, 0, resultBitmap.Width, resultBitmap.Height), ImageLockMode.WriteOnly, PixelFormat.Format32bppArgb);
Marshal.Copy(pixelBuffer, 0, resultData.Scan0, pixelBuffer.Length); resultBitmap.UnlockBits(resultData);
return resultBitmap; }
In order to manipulate pixel colour component values directly we first need to lock the source Bitmap into memory by invoking the Bitmap.LockBits method. Once the source Bitmap is locked into memory we can copy the underlying pixel buffer using the Marshal.Copy method.
The next step involves iterating through the byte buffer of colour components. Notice how each iteration modifies an entire pixel by iterating by 4. As discussed earlier when implementing image solarisation the associated formula employs threshold comparison, which determines whether or not colour inversion should be applied.
The final operation performed by the Solarise method involves copying the modified pixel buffer into a newly created Bitmap object which will be returned to the calling code.
Sample Images
The original source image used to create all of the solarised sample images in this article has been licensed under the Creative Commons Attribution-Share Alike 3.0 Unported, 2.5 Generic, 2.0 Generic and 1.0 Generic license. The original image is attributed to Kenneth Dwain Harrelson and can be downloaded from Wikipedia.
The Original Image
Solarised Images
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
![]() |
Related Articles
- C# How to: Image filtering by directly manipulating Pixel ARGB values
- C# How to: Image filtering implemented using a ColorMatrix
- C# How to: Blending Bitmap images using colour filters
- C# How to: Bitmap Colour Substitution implementing thresholds
- C# How to: Generating Icons from Images
- C# How to: Swapping Bitmap ARGB Colour Channels
- C# How to: Bitmap Pixel manipulation using LINQ Queries
- C# How to: Linq to Bitmaps – Partial Colour Inversion
- C# How to: Bitmap Colour Balance
- C# How to: Bi-tonal Bitmaps
- C# How to: Bitmap Colour Tint
- C# How to: Bitmap Colour Shading
- C# How to: Image Solarise
- C# How to: Image Contrast
- C# How to: Bitwise Bitmap Blending