Unsafe code on a webserver - 2bpp images
-
We're doing some bitmap manipulation and have come up against the issue of not being able to create a 2bpp bitmap. So we've implemented the following class:
public class BitmapSubsystem { public static readonly BitmapSubsystem Instance = new BitmapSubsystem(); protected ColorPalette GetMonoColorPalette() { // Make a new Bitmap object to get its Palette. Bitmap bitmap = new Bitmap( 1, 1, PixelFormat.Format1bppIndexed ); ColorPalette palette = bitmap.Palette; // Grab the palette palette.Entries[0] = Color.FromArgb( (int)0xFF, (int)0, (int)0,(int)0 ); // Black palette.Entries[1] = Color.FromArgb( (int)0, (int)255, (int)255,(int)255 ); // Transparent bitmap.Dispose(); // cleanup the source Bitmap return palette; // Send the palette back } public void ConvertTo2bppBitmap( Bitmap sourceBitmap, Stream output ) { // Make a new 8-BPP indexed bitmap that is the same size as the source image. int Width = sourceBitmap.Width; int Height = sourceBitmap.Height; // Always use PixelFormat8bppIndexed because that is the color // table-based interface to the GIF codec. Bitmap bitmap = new Bitmap(Width, Height, PixelFormat.Format8bppIndexed); try { // Create a color palette big enough to hold the colors you want. ColorPalette pal = GetMonoColorPalette(); // Set the palette into the new Bitmap object. bitmap.Palette = pal; // Lock a rectangular portion of the bitmap for writing. BitmapData bitmapData; Rectangle rect = new Rectangle(0, 0, Width, Height); bitmapData = bitmap.LockBits( rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); // Write to the temporary buffer that is provided by LockBits. // Copy the pixels from the source image in this loop. // Because you want an index, convert RGB to the appropriate // palette index here. IntPtr pixels = bitmapData.Scan0; unsafe { // Get the pointer to the image bits. // This is the unsafe operation. byte * pBits; if (bitmapData.Stride > 0) pBits = (byte *)pixels.ToPointer(); else // If the Stride is negative, Scan0 points to the last // scanline in the buffer. To normalize the loop, obtain // a pointer to the front of the buffer that is located // (Height-1) scanlines previous. pBits = (byte *)pixels.ToPointer() + bitmapData.Stride*(Height-1); uint stride = (uint)Math.
-
We're doing some bitmap manipulation and have come up against the issue of not being able to create a 2bpp bitmap. So we've implemented the following class:
public class BitmapSubsystem { public static readonly BitmapSubsystem Instance = new BitmapSubsystem(); protected ColorPalette GetMonoColorPalette() { // Make a new Bitmap object to get its Palette. Bitmap bitmap = new Bitmap( 1, 1, PixelFormat.Format1bppIndexed ); ColorPalette palette = bitmap.Palette; // Grab the palette palette.Entries[0] = Color.FromArgb( (int)0xFF, (int)0, (int)0,(int)0 ); // Black palette.Entries[1] = Color.FromArgb( (int)0, (int)255, (int)255,(int)255 ); // Transparent bitmap.Dispose(); // cleanup the source Bitmap return palette; // Send the palette back } public void ConvertTo2bppBitmap( Bitmap sourceBitmap, Stream output ) { // Make a new 8-BPP indexed bitmap that is the same size as the source image. int Width = sourceBitmap.Width; int Height = sourceBitmap.Height; // Always use PixelFormat8bppIndexed because that is the color // table-based interface to the GIF codec. Bitmap bitmap = new Bitmap(Width, Height, PixelFormat.Format8bppIndexed); try { // Create a color palette big enough to hold the colors you want. ColorPalette pal = GetMonoColorPalette(); // Set the palette into the new Bitmap object. bitmap.Palette = pal; // Lock a rectangular portion of the bitmap for writing. BitmapData bitmapData; Rectangle rect = new Rectangle(0, 0, Width, Height); bitmapData = bitmap.LockBits( rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed); // Write to the temporary buffer that is provided by LockBits. // Copy the pixels from the source image in this loop. // Because you want an index, convert RGB to the appropriate // palette index here. IntPtr pixels = bitmapData.Scan0; unsafe { // Get the pointer to the image bits. // This is the unsafe operation. byte * pBits; if (bitmapData.Stride > 0) pBits = (byte *)pixels.ToPointer(); else // If the Stride is negative, Scan0 points to the last // scanline in the buffer. To normalize the loop, obtain // a pointer to the front of the buffer that is located // (Height-1) scanlines previous. pBits = (byte *)pixels.ToPointer() + bitmapData.Stride*(Height-1); uint stride = (uint)Math.
Anyone? :) ________________________ http://www.webreaper.net