Home
Manage Your Code
Snippet: Presentation Framework Imaging Classes Gray-Scale Example (loading, drawing, encoding) (C#)
Title: Presentation Framework Imaging Classes Gray-Scale Example (loading, drawing, encoding) Language: C#
Description: a quick example of how to implement the Presentation Framework imaging classes. Views: 360
Author: Bryan Lyman Date Added: 10/13/2011
Copy Code  
1/*
2Notice how I am manipulating the RGB values of each pixel, this is the power of these classes. The Drawing classes have the 
3pixel drawing capabilities to draw lines and such already written for you, but handling a grayscale byte for byte is faster 
4than relying on their other classes. I also chose to load and encode as PNG, but they have loaders and encoders for other 
5file types as well that work the same way.
6*/
7
8using System;
9using System.IO;
10using System.Windows.Media.Imaging;
11using System.Windows.Media;
12 
13namespace MyNamespace.Imaging
14{
15  public sealed partial class MyImageClass
16  {
17     public enum eBpp : byte { _1 = 0, _8 = 1, _16 = 2, _24 = 3, _32 = 4, _40 = 5, _48 = 6, _56 = 7, _64 = 8, _128 = 16 }
18 
19     public static BitmapSource LoadPng(string fileName)
20     {
21        FileStream fs = File.OpenRead(fileName);
22        byte[] data = new byte[fs.Length];
23        fs.Read(data, 0, (int)fs.Length);
24        fs.Close();
25        MemoryStream ms = new MemoryStream(data);					
26	PngBitmapDecoder decoder = new PngBitmapDecoder(ms, BitmapCreateOptions.None, BitmapCacheOption.None);
27	return decoder.Frames[0];
28     }
29 
30     public static void MakeGrayScale(ref BitmapSource image)
31     {
32        byte bytes = (byte)(eBpp)Enum.Parse(typeof(eBpp), "_" + image.Format.BitsPerPixel);
33  	int stride = image.PixelWidth * bytes;
34	long size = image.PixelHeight * stride;
35	byte[] source = new byte[size];
36	image.CopyPixels(source, stride, 0);
37	byte[] dest = new byte[size];
38	if (image.Format.BitsPerPixel == 32)		
39	{
40		for (int i = bytes - 1; i < size; i += bytes)
41		{
42			uint avrg = (uint)source[i - 3] + (uint)source[i - 2] + (uint)source[i - 1];
43			if (avrg != 0)
44				avrg = avrg / 3;
45 
46			dest[i - 3] = (byte)avrg;
47			dest[i - 2] = (byte)avrg;
48			dest[i - 1] = (byte)avrg;
49			dest[i] = source[i]; //alpha

50		}
51	} //aren't handling any other types than 32bit color, but these can be added easily

52 
53        image = BitmapSource.Create(image.PixelWidth, image.PixelHeight, 96, 96, image.Format, BitmapPalettes.Halftone256Transparent, dest, stride);
54      }
55 
56      public static MemoryStream PngEncode(BitmapSource image)
57      {			
58	//encode image as png

59	PngBitmapEncoder encoder = new PngBitmapEncoder();
60	encoder.Interlace = PngInterlaceOption.On;
61	encoder.Frames.Add(BitmapFrame.Create(image));
62	MemoryStream ret = new MemoryStream(); //create valid return stream

63	encoder.Save(ret);
64	ret.Position = 0;
65	return ret;
66      }
67   }
68}
Usage
BitmapSource png = MyImageClass.LoadPng("test.png");
MyImageClass.MakeGrayScale(png);
MemoryStream outStream = MyImageClass.PngEncode(png);
Notes
You must include these DLL references in your vsweb or vscode project: PresentationCore, PresentationFramework, WindowsBase.