Archive for the 'Tip' Category



C# How to: Bitmap Pixel manipulation using LINQ Queries

Article Purpose

In this article we explore manipulating a  ’s underlying pixel data. The process of Pixel data manipulation at its core feature the implementation of Queries targeting raw pixel data.

Update: I’ve published a follow-up article – Part 2: The banner images in this article were generated using the concepts explored in the follow-up article. The source image has been licenced under the Creative Commons Attribution-Share Alike 3.0 Unported license and can be downloaded from .

Led_Banner1

Sample source code

This article is accompanied by a sample source code Visual Studio project which is available for download here.

Led_Banner2

Using the sample Application

This article’s associated sample source code defines a sample application, detailing the concepts explored by this article. The sample application implements two types of image filters: Swapping each pixel’s colour components and shifting pixels to different locations within the image data buffer.

The image shown below is a screenshot of the Bitmap Pixel Manipulation application in action:

BitmapPixelManipulation

The sample application allows the user to specify an input source image which can then be modified by implementing an image filter. If desired the user has the option to save the new/result image to the file system.

Led_Banner3

Extracting Pixel values from a Bitmap image

The sample source code defines the ArgbPixel class which is implemented to represent an individual pixel. The definition as follows:

public class ArgbPixel
{
    public byte blue = 0;
    public byte green = 0;
    public byte red = 0;
    public byte alpha = 0;

public ArgbPixel() { }
public ArgbPixel(byte[] colorComponents) { blue = colorComponents[0]; green = colorComponents[1]; red = colorComponents[2]; alpha = colorComponents[3]; }
public byte[] GetColorBytes() { return new byte[]{blue, green, red, alpha}; } }

Each pixel is defined by four member variables of type byte: blue, red, green and alpha. The ArgbPixel class defines an overloaded constructor which allows for creating an instance by specifying the four colour components as byte values. By invoking the GetColorBytes method the calling code can access the underlying colour component byte values in the form of a byte array.

Led_Banner1

The Colour Swap filter

The Colour swap filter acts as an image filter by implementing various combinations of swapping each individual pixel’s Alpha, Red, Green and Blue colour channels. The sample source code defines the ColorSwapType , intended to provide a collection of possible pixel colour channel swap operations. The code snippet listed below provides the definition of the ColorSwapType type:

public enum ColourSwapType
{
    ShiftRight,
    ShiftLeft,
    SwapBlueAndRed,
    SwapBlueAndRedFixGreen,
    SwapBlueAndGreen,
    SwapBlueAndGreenFixRed,
    SwapRedAndGreen,
    SwapRedAndGreenFixBlue
}

The following section provides an explanation of each Colour Swap method:

  • ShiftRight – Starting with Blue each colour channel’s value will be copied to the colour channel to the right.
  • ShiftLeft – Starting with Blue each colour channel’s value will be copied to the colour channel to the left.
  • SwapBlueAndRed – Blue and Red values are swapped, Green remains unchanged.
  • SwapBlueAndRedFixGreen – Blue and Red values are swapped, each pixel’s Green value is set to the same value as specified by the calling code.
  • SwapBlueAndGreen – Blue and Green values are swapped, Red remains unchanged.
  • SwapBlueAndGreenFixRed – Blue and Green values are swapped, each pixel’s Red value is set to the same value as specified by the calling code.
  • SwapRedAndGreen – Red and Green values are swapped, Blue remains unchanged.
  • SwapRedAndGreenFixBlue – Red and Green values are swapped, each pixel’s Blue value is set to the same value as specified by the calling code.

Led_Banner2

From a Bitmap buffer to a Pixel List

The sample source provides the definition for the GetPixelListFromBitmap method. The purpose behind this method is to read a ’s underlying colour component byte buffer data and create a generic collection of type ArgbPixel. By representing the data as a generic collection we are able implement query operations. The code snippet below details the GetPixelListFromBitmap method definition.

private static List<ArgbPixel> GetPixelListFromBitmap(Bitmap sourceImage)
{
     BitmapData sourceData = sourceImage.LockBits(new Rectangle(0, 0, 
                 sourceImage.Width, sourceImage.Height), 
                 ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);

byte[] sourceBuffer = new byte[sourceData.Stride * sourceData.Height]; Marshal.Copy(sourceData.Scan0, sourceBuffer, 0, sourceBuffer.Length); sourceImage.UnlockBits(sourceData);
List<ArgbPixel> pixelList = new List<ArgbPixel>(sourceBuffer.Length / 4);
using (MemoryStream memoryStream = new MemoryStream(sourceBuffer)) { memoryStream.Position = 0; BinaryReader binaryReader = new BinaryReader(memoryStream);
while (memoryStream.Position + 4 <= memoryStream.Length) { ArgbPixel pixel = new ArgbPixel(binaryReader.ReadBytes(4)); pixelList.Add(pixel); }
binaryReader.Close(); }
return pixelList; }

The GetPixelListFromBitmap accepts a parameter and returns a generic collection of type ArgbPixel. Within the method body the first operation performed involves locking the pixel data in memory by invoking the method. By locking data in memory we are in effect signalling the to not shift around in memory the underlying data whilst we are busy accessing the data.

Next, the sample source code implements the method in order to copy the ’s colour component data in the form of a byte array. Once we’ve copied the pixel data we can unlock the by invoking .

The final operation performed by the GetPixelListFromBitmap involves iterating through the byte array of colour components. With each loop we make use of a , reading four bytes at a time and passing the result to the overloaded constructor exposed by the ArgbPixel class.

Led_Banner3

Applying Linq queries to Pixel Data

This article’s sample source code implements queries through the SwapColors extension method which targets the Bitmap class. The definition is detailed by the following code snippet:

 public static Bitmap SwapColors(this Bitmap sourceImage, 
                                 ColourSwapType swapType, 
                                 byte fixedValue = 0)
{
     List<ArgbPixel> pixelListSource = GetPixelListFromBitmap(sourceImage);

List<ArgbPixel> pixelListResult = null;
switch (swapType) { case ColourSwapType.ShiftRight: { pixelListResult = (from t in pixelListSource select new ArgbPixel { blue = t.red, red = t.green, green = t.blue, alpha = t.alpha}).ToList(); break; } case ColourSwapType.ShiftLeft: { pixelListResult = (from t in pixelListSource select new ArgbPixel { blue = t.green, red = t.blue, green = t.red, alpha = t.alpha}).ToList(); break; } case ColourSwapType.SwapBlueAndRed: { pixelListResult = (from t in pixelListSource select new ArgbPixel { blue = t.red, red = t.blue, green = t.green, alpha = t.alpha}).ToList(); break; case ColourSwapType.SwapBlueAndRedFixGreen: { pixelListResult = (from t in pixelListSource select new ArgbPixel { blue = t.red, red = t.blue, green = fixedValue, alpha = t.alpha}).ToList(); break; } case ColourSwapType.SwapBlueAndGreen: { pixelListResult = (from t in pixelListSource select new ArgbPixel { blue = t.green, red = t.red, green = t.blue, alpha = t.alpha}).ToList(); break; } case ColourSwapType.SwapBlueAndGreenFixRed: { pixelListResult = (from t in pixelListSource select new ArgbPixel { blue = t.green, red = fixedValue, green = t.blue, alpha = t.alpha}).ToList(); break; } case ColourSwapType.SwapRedAndGreen: { pixelListResult = (from t in pixelListSource select new ArgbPixel { blue = t.blue, red = t.green, green = t.red, alpha = t.alpha}).ToList(); break; } case ColourSwapType.SwapRedAndGreenFixBlue: { pixelListResult = (from t in pixelListSource select new ArgbPixel { blue = fixedValue, red = t.green, green = t.red, alpha = t.alpha}).ToList(); break; } }
Bitmap resultBitmap = GetBitmapFromPixelList(pixelListResult, sourceImage.Width, sourceImage.Height);
return resultBitmap; }

The SwapColors extension method accepts as parameters an value of type ColourSwapType and a byte parameter fixedValue defined with a default value of 0.

The GetPixelListFromBitmap method discussed earlier is implemented in order to create a generic of type ArgbPixel. The bulk of the method’s implementation is performed next by applying a switch statement on the ColourSwapType parameter. The original List<ArgbPixel> collection is used to populate a resulting List<ArgbPixel> collection. Assignment from source to result collection occurs through a query implementing the relevant ColourSwapType.

The last operation performed by the SwapColors extension method involves converting the resulting List<ArgbPixel> collection back to a object through invoking the GetBitmapFromPixelList method. The following section provides a description of the GetBitmapFromPixelList method.

Led_Banner1

From a Pixel List to a Bitmap

In the sample source code the GetPixelListFromBitmap method discussed earlier, is complimented by its inverse, the GetBitmapFromPixelList method. As the name implied the GetBitmapFromPixelList method’s purpose is to convert a generic of type ArgbPixel to a object. The definition as follows:

private static Bitmap GetBitmapFromPixelList(List<ArgbPixel> pixelList, int width, int height)
{
     Bitmap resultBitmap = new Bitmap(width, height, PixelFormat.Format32bppArgb);

BitmapData resultData = resultBitmap.LockBits(new Rectangle(0, 0, resultBitmap.Width, resultBitmap.Height), ImageLockMode.ReadOnly, PixelFormat.Format32bppArgb);
byte[] resultBuffer = new byte[resultData.Stride * resultData.Height];
using (MemoryStream memoryStream = new MemoryStream(resultBuffer)) { memoryStream.Position = 0; BinaryWriter binaryWriter = new BinaryWriter(memoryStream);
foreach (ArgbPixel pixel in pixelList) { binaryWriter.Write(pixel.GetColorBytes()); }
binaryWriter.Close(); }
Marshal.Copy(resultBuffer, 0, resultData.Scan0, resultBuffer.Length); resultBitmap.UnlockBits(resultData);
return resultBitmap; }

The GetBitmapFromPixelList method accepts as parameters a generic of type ArgbPixel, width and height of type int. The width and height parameters indicates the size of the original , which will be used when creating a new resulting .

The first step performed by the GetBitmapFromPixelList method is to create a resulting object and locking into memory the underlying data by invoking the method.

The bulk of the work performed by the GetBitmapFromPixelList method occurs in the form of iterating the List of ArgbPixel parameter and writing the Pixel’s underlying colour components to a byte buffer related to the resulting .

In the last step being performed byte array of colour component data is copied to the resulting by invoking .

Led_Banner2

Reversing a List of Pixels

As an additional example the sample source code also defines the FlipPixels extension method. This method provides a quick implementation of turning a image upside down. The implementation as follows:

public static Bitmap FlipPixels(this Bitmap sourceImage)
{
     List<ArgbPixel> pixelList = GetPixelListFromBitmap(sourceImage);

pixelList.Reverse();
Bitmap resultBitmap = GetBitmapFromPixelList(pixelList, sourceImage.Width, sourceImage.Height);
return resultBitmap; }

The FlipPixels extension method targets the class and returns a object. As discussed earlier the method invokes the GetPixelListFromBitmap and GetBitmapFromPixelList methods. Reversing the order of the ArgbPixel objects is achieved through invoking the method.

Led_Banner3

Filter implementation examples

This section contains the eye candy of this article. The following set of images were created from a single input source image. The original image is licensed under the Creative Commons Attribution 2.0 Generic license and can be downloaded from Wikipedia.

The Original Image

SunflowerSunset2

Shift Left

ShiftLeft

Shift Right

ShiftRight

Swap Blue and Red

SwapBlueAndRed

Swap Blue and Red, fix Green at 0

SwapBlueAndRedFixGreen0

Swap Blue and Green

SwapBlueAndGreen

Swap Blue and Green, fix Red at 25

SwapBlueAndGreenFixRed25

Swap Red and Green

SwapRedAndGreen

Swap Red and Green, fix Blue at 0

SwapRedAndGreenFixBlue0

Swap Red and Green, fix Blue at 115

SwapRedAndGreenFixBlue115

Swap Red and Green, fix Blue at 200

SwapRedAndGreenFixBlue200

RSS Feed Buttons

Overview

I’ve been experimenting with lately. As an example showcasing some of the possibilities I created several images based on the standard orange RSS feed icon.

The source image used in generating all the filtered images on this page has been licensed under the and can be

If you are interested in the technical details behind the implementation you can browse the C# How to articles at and .

RSS Buttons

The following section provides a thumbnails preview of the images I created. Please note that all images have the size dimension of 2000×2000 pixels. I’ve opted to provide high resolution images to accommodate better results should images be edited further. It is not recommended using high resolution images directly due to larger file sizes when compared to typically used lower resolution images. Reducing image resolution is a fairly straight forward task easily achieved using most image editing software.

Images are provided under the . You are free to download, modify and redistribute the images.

To download an image simply click on the relevant thumbnail.

RSS Button Blue Grey RSS Button Bright Green RSS Button Brown LightBlue RSS Button Brown LightPurple RSS Button DarkBlue RSS Button DarkBlue RSS Button DarkBlue LightBlue RSS Button DarkBlue Red RSS Button DarkOrange LightOrange RSS Button DarkPink LightPurple RSS Button DarkPurple Blue RSS Button DarkPurple LightPurple RSS Button DarkPurple MediumBlue RSS Button Green DarkPink RSS Button Green LightBlue RSS Button LightBlue RSS Button Maroon Purple RSS Button Orange Yellow RSS Button PinkTint RSS Button PurpleTint RSS Button SeaGreen LightYellow RSS Button Violet DarkPink RSS Green Button RSS Purple Button

Image Filters: The Red Hot Chilli Peppers live in concert

The Original

All of the images featured in this article were generated from the same the input source image file. Each image illustrates the implementation of a different colour filter.

The original source image is a photo I had taken myself during a live concert performance by The Red Hot Chilli Peppers, performed at Soccer City, Johannesburg, South Africa.

The colour filter technical details are explored in the articles: C# How to: Blending Bitmap images using colour filters and C# How to: Swapping Bitmap ARGB Colour Channels.

Original Image

RHCP_Original

Filtered Images

RHCP_AmberRHCP_BlueGreenRHCP_BluePinkRHCP_BrightBlueRHCP_BrightBlueTintRHCP_BrightGreenRHCP_BrightGreenTintRHCP_BrightWhiteRHCP_BrightYellowRHCP_DarkPinkRHCP_GreenRHCP_GreenYellowTintRHCP_LavenderRHCP_LightBlueRHCP_NeonGreenRHCP_OrangeRHCP_VioletRHCP_Yellow

Image Filters: Tropical Storm

The Original Image

The original image file has been released into the public domain. Download the original from Wikipedia.

All or the images featured in this set were created using the original image and applying various colour filters. The colour filter technical details are explored in the articles: C# How to: Blending Bitmap images using colour filters and C# How to: Swapping Bitmap ARGB Colour Channels.

Original Image

17W_Aug_14_1996_0124Z

Filtered Images

TropicalStorm_BrightBlueBlendTropicalStorm_GreenGrayBlend

TropicalStorm_LightPinkBlendTropicalStorm_LightTanBlend

TropicalStorm_OffWhiteBlendTropicalStorm_OrangeBlend

TropicalStorm_PurpleBlendTropicalStorm_RedBlend

TropicalStorm_ShiftLeft_InvertedTropicalStorm_ShiftRight_Inverted

TropicalStorm_SwapBlueAndGreen_InvertedTropicalStorm_SwapBlueAndRed_Inverted

TropicalStorm_SwapRedAndGreen_InvertedTropicalStorm_VoiletBlend

Create and download PDF documents on Wikipedia.org

Overview

I consider Wikipedia.org as one of my favourite and definitely most used online resources. Recently I unintentionally discovered a really useful feature exposed by Wikipedia: Compiling ebooks from one or several Wikipedia articles. Being able to neatly package Wikipedia content for offline reference use can prove to be very useful in certain scenarios.

The Wikipedia Book Creator

The process of compiling and managing ebook formatted Wikipedia content is the responsibility of the Wikipedia Book Creator. The first step in using the Book Creator would to make sure you’ve enable Book Creator.

Wikipedia’s navigation pane on the left-hand side of the screen provides a link to enable Book Creator, located under the Print/Export option:

WikipediaBookCreator

After clicking the Create a Book link, the page that loads next provides a button to start the Book Creator:

WikipediaBookCreatorEnable

In addition on this page you will find instructions relating to how to make use of the Book Creator feature. More in depth information can be found on the Book Creator Help page.

Once you’ve enabled the Book Creator you can continue browsing Wikipedia as per normal, with the exception of specifying which article pages should be added to your book.

Adding Article pages

You will notice that at the top of each Wikipedia article page you are now presented with additional links allowing you to interact with the Book Creator. As you browse through articles on Wikipedia you only have to click the link titled Add this page to your book.

BookCreator_AddArticlePages

Compiling and Downloading your Wikipedia eBook

When you decide that you have included enough article content in your book you can start reviewing your book by clicking the Show Book link located towards the top of the page.

When reviewing your book you can remove Wikipedia articles you no longer want to include in the final eBook, additionally you can specify the book’s title and subtitle.

BookCreator_Review

The final step required to create your book is to specify the eBook format you prefer and then to click download.

BookCreator_Download

Do note that Wikipedia also provides a service allowing users to order a printed copy of the eBook being generated.

In the steps illustrated above I created a PDF format eBook referencing Microsoft’s Wikipedia page. You can download the generated eBook here.


Dewald Esterhuizen

Unknown's avatar

Blog Stats

  • 892,466 hits

Enter your email address to follow and receive notifications of new posts by email.

Join 91 other subscribers

Archives

RSS SoftwareByDefault on MSDN

  • An error has occurred; the feed is probably down. Try again later.