Click here to Skip to main content
15,894,907 members
Home / Discussions / C#
   

C#

 
GeneralThreading.Timer callback called multiple times Pin
sjhart12-Apr-05 0:23
sjhart12-Apr-05 0:23 
GeneralRe: Threading.Timer callback called multiple times Pin
Mike Dimmick12-Apr-05 2:43
Mike Dimmick12-Apr-05 2:43 
GeneralRe: Threading.Timer callback called multiple times Pin
sjhart12-Apr-05 3:05
sjhart12-Apr-05 3:05 
GeneralC#, COM & Type Libraries Pin
MrEyes12-Apr-05 0:13
MrEyes12-Apr-05 0:13 
Questionhow to send http streams in c# Pin
arusmemon11-Apr-05 23:53
arusmemon11-Apr-05 23:53 
AnswerRe: how to send http streams in c# Pin
Claudio Grazioli12-Apr-05 3:05
Claudio Grazioli12-Apr-05 3:05 
GeneralRe: Setting file attributes Pin
hooray12-Apr-05 1:10
hooray12-Apr-05 1:10 
GeneralUnsafe code on a webserver - 2bpp images Pin
Mark Otway11-Apr-05 23:39
Mark Otway11-Apr-05 23:39 
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:

<br />
	public class BitmapSubsystem<br />
	{<br />
		public static readonly BitmapSubsystem Instance = new BitmapSubsystem();<br />
<br />
		protected ColorPalette GetMonoColorPalette()<br />
		{<br />
			// Make a new Bitmap object to get its Palette.<br />
			Bitmap bitmap = new Bitmap( 1, 1, PixelFormat.Format1bppIndexed );<br />
<br />
			ColorPalette palette = bitmap.Palette;   // Grab the palette<br />
<br />
			palette.Entries[0] = Color.FromArgb( (int)0xFF, (int)0, (int)0,(int)0 ); // Black<br />
			palette.Entries[1] = Color.FromArgb( (int)0, (int)255, (int)255,(int)255 ); // Transparent<br />
<br />
			bitmap.Dispose();           // cleanup the source Bitmap<br />
<br />
			return palette;             // Send the palette back<br />
		}<br />
<br />
		public void ConvertTo2bppBitmap( Bitmap sourceBitmap, Stream output )<br />
		{<br />
			// Make a new 8-BPP indexed bitmap that is the same size as the source image.<br />
			int   Width = sourceBitmap.Width;<br />
			int   Height = sourceBitmap.Height;<br />
<br />
			// Always use PixelFormat8bppIndexed because that is the color<br />
			// table-based interface to the GIF codec.<br />
			Bitmap  bitmap = new Bitmap(Width, Height, PixelFormat.Format8bppIndexed);<br />
<br />
			try<br />
			{<br />
				// Create a color palette big enough to hold the colors you want.<br />
				ColorPalette pal = GetMonoColorPalette();<br />
<br />
				// Set the palette into the new Bitmap object.<br />
				bitmap.Palette = pal;<br />
<br />
				// Lock a rectangular portion of the bitmap for writing.<br />
				BitmapData  bitmapData;<br />
				Rectangle   rect = new Rectangle(0, 0, Width, Height);<br />
<br />
				bitmapData = bitmap.LockBits( rect, ImageLockMode.WriteOnly, PixelFormat.Format8bppIndexed);<br />
<br />
				// Write to the temporary buffer that is provided by LockBits.<br />
				// Copy the pixels from the source image in this loop.<br />
				// Because you want an index, convert RGB to the appropriate<br />
				// palette index here.<br />
				IntPtr pixels = bitmapData.Scan0;<br />
<br />
				unsafe<br />
				{<br />
					// Get the pointer to the image bits.<br />
					// This is the unsafe operation.<br />
					byte *  pBits;<br />
					if (bitmapData.Stride > 0)<br />
						pBits = (byte *)pixels.ToPointer();<br />
					else<br />
						// If the Stride is negative, Scan0 points to the last<br />
						// scanline in the buffer. To normalize the loop, obtain<br />
						// a pointer to the front of the buffer that is located<br />
						// (Height-1) scanlines previous.<br />
						pBits = (byte *)pixels.ToPointer() + bitmapData.Stride*(Height-1);<br />
					<br />
					uint stride = (uint)Math.Abs(bitmapData.Stride);<br />
<br />
					for ( uint row = 0; row < Height; ++row )<br />
					{<br />
						for ( uint col = 0; col < Width; ++col )<br />
						{<br />
							// Map palette indexes for a gray scale.<br />
							// If you use some other technique to color convert,<br />
							// put your favorite color reduction algorithm here.<br />
<br />
							// The destination pixel.<br />
							// The pointer to the color index byte of the<br />
							// destination; this real pointer causes this<br />
							// code to be considered unsafe.<br />
							byte *    p2bppPixel = pBits + row*stride + col;<br />
<br />
							Color srcPixel = sourceBitmap.GetPixel((int)col, (int)row);<br />
<br />
							// This expression is best as integer math for performance,<br />
							// however, because GetPixel listed earlier is the slowest<br />
							// part of this loop, the expression is left as<br />
							// floating point for clarity.<br />
							double luminance = (srcPixel.R *0.299) + (srcPixel.G *0.587) + (srcPixel.B *0.114);<br />
<br />
							// If the luminance is > 0 then use the non-transparent palette entry<br />
							if( luminance > 0 )<br />
								*p2bppPixel = (byte)(1);<br />
							else<br />
								*p2bppPixel = (byte)(0);<br />
<br />
						} /* end loop for col */<br />
					} /* end loop for row */<br />
				} /* end unsafe */<br />
<br />
				// To commit the changes, unlock the portion of the bitmap.<br />
				bitmap.UnlockBits(bitmapData);<br />
<br />
				bitmap.Save(output, ImageFormat.Gif);<br />
			}<br />
			catch<br />
			{<br />
			}<br />
<br />
			// Bitmap goes out of scope here and is also marked for<br />
			// garbage collection.<br />
			// Pal is referenced by bitmap and goes away.<br />
			bitmap.Dispose();<br />
		}	<br />


This uses some unsafe pointer manipulation to copy the bitmap across to a 2bpp image with transparency, and does the job nicely.

Question is, can this code be rewritten as managed code (using SetPixel/GetPixel)? I know it'll be a little slower, but we're only working on bitmaps that are 40px by 16px, so performance isn't too much of an issue. But SetPixel doesn't seem to allow me to set pixels on a 2bpp image - it seems to expect an ARGB value, rather than a pallette index....

If it can't be written as managed code, what are the implications of publishing unsafe code like the above? Is there a risk to my production webserver?

________________________
http://www.webreaper.net
GeneralRe: Unsafe code on a webserver - 2bpp images Pin
Mark Otway12-Apr-05 20:38
Mark Otway12-Apr-05 20:38 
GeneralError in DataBinding after DataSet.Clear() Pin
Vexta11-Apr-05 21:47
Vexta11-Apr-05 21:47 
GeneralCheckbox Controls in a form Pin
Billy Whizz11-Apr-05 21:02
Billy Whizz11-Apr-05 21:02 
GeneralRe: Checkbox Controls in a form Pin
Dave Kreskowiak12-Apr-05 7:02
mveDave Kreskowiak12-Apr-05 7:02 
GeneralConvert string to a string array Pin
myNameIsRon11-Apr-05 19:29
myNameIsRon11-Apr-05 19:29 
GeneralRe: Convert string to a string array Pin
Robert Rohde11-Apr-05 19:41
Robert Rohde11-Apr-05 19:41 
GeneralRe: Convert string to a string array Pin
myNameIsRon11-Apr-05 19:56
myNameIsRon11-Apr-05 19:56 
GeneralRe: Convert string to a string array Pin
techieboi12-Apr-05 5:33
techieboi12-Apr-05 5:33 
GeneralI need advice on class design Pin
tantiboh11-Apr-05 19:12
tantiboh11-Apr-05 19:12 
GeneralRe: I need advice on class design Pin
Christian Graus11-Apr-05 19:26
protectorChristian Graus11-Apr-05 19:26 
GeneralRe: I need advice on class design Pin
tantiboh11-Apr-05 19:45
tantiboh11-Apr-05 19:45 
GeneralRe: I need advice on class design Pin
Skynyrd12-Apr-05 1:18
Skynyrd12-Apr-05 1:18 
GeneralRe: I need advice on class design Pin
tantiboh12-Apr-05 6:55
tantiboh12-Apr-05 6:55 
Generaldifference between GetType() method , is operator and typeof operator Pin
RuchirD11-Apr-05 17:52
RuchirD11-Apr-05 17:52 
GeneralRe: difference between GetType() method , is operator and typeof operator Pin
S. Senthil Kumar11-Apr-05 18:41
S. Senthil Kumar11-Apr-05 18:41 
Generaldata access problem Pin
brian5511-Apr-05 17:47
brian5511-Apr-05 17:47 
GeneralRe: data access problem Pin
mhmoud rawas11-Apr-05 23:15
mhmoud rawas11-Apr-05 23:15 

General General    News News    Suggestion Suggestion    Question Question    Bug Bug    Answer Answer    Joke Joke    Praise Praise    Rant Rant    Admin Admin   

Use Ctrl+Left/Right to switch messages, Ctrl+Up/Down to switch threads, Ctrl+Shift+Left/Right to switch pages.