Click here to Skip to main content
15,895,011 members
Articles / Mobile Apps

Symmetry Drawing Tool

Rate me:
Please Sign up or sign in to vote.
4.11/5 (30 votes)
31 May 2004CPOL3 min read 84.1K   1.7K   46  
An article describing the development and use of the Symmetry Drawing Tool.
  • symmetrydraw.zip
    • SymmetricDraw
      • App.ico
      • AssemblyInfo.cs
      • bin
        • Release
          • SymmetricDraw.exe
          • SymmetricDrawCE.exe
      • Bitmaps
        • Axes.bmp
        • Clear.bmp
        • Color.bmp
        • ColorSel.bmp
        • Filled.bmp
        • happy.bmp
        • Mirror.bmp
        • Open.bmp
        • Save.bmp
        • shape.bmp
        • Stamp.bmp
      • BitmapSaver.cs
      • cab
        • Release
          • CabWiz.PPC.log
          • CabWiz.WCE4.log
          • SymmetricDrawCE_PPC.ARM.CAB
          • SymmetricDrawCE_PPC.ARM.DAT
          • SymmetricDrawCE_PPC.ARMV4.CAB
          • SymmetricDrawCE_PPC.ARMV4.DAT
          • SymmetricDrawCE_PPC.MIPS.CAB
          • SymmetricDrawCE_PPC.MIPS.DAT
          • SymmetricDrawCE_PPC.SH3.CAB
          • SymmetricDrawCE_PPC.SH3.DAT
          • SymmetricDrawCE_PPC.WCE420X86.CAB
          • SymmetricDrawCE_PPC.WCE420X86.DAT
          • SymmetricDrawCE_PPC.X86.CAB
          • SymmetricDrawCE_PPC.X86.DAT
          • SymmetricDrawCE_WCE4.ARMV4.CAB
          • SymmetricDrawCE_WCE4.ARMV4.DAT
          • SymmetricDrawCE_WCE4.ARMV4T.CAB
          • SymmetricDrawCE_WCE4.ARMV4T.DAT
          • SymmetricDrawCE_WCE4.MIPS16.CAB
          • SymmetricDrawCE_WCE4.MIPS16.DAT
          • SymmetricDrawCE_WCE4.MIPSII.CAB
          • SymmetricDrawCE_WCE4.MIPSII.DAT
          • SymmetricDrawCE_WCE4.MIPSII_FP.CAB
          • SymmetricDrawCE_WCE4.MIPSII_FP.DAT
          • SymmetricDrawCE_WCE4.MIPSIV.CAB
          • SymmetricDrawCE_WCE4.MIPSIV.DAT
          • SymmetricDrawCE_WCE4.MIPSIV_FP.CAB
          • SymmetricDrawCE_WCE4.MIPSIV_FP.DAT
          • SymmetricDrawCE_WCE4.SH3.CAB
          • SymmetricDrawCE_WCE4.SH3.DAT
          • SymmetricDrawCE_WCE4.SH4.CAB
          • SymmetricDrawCE_WCE4.SH4.DAT
          • SymmetricDrawCE_WCE4.X86.CAB
          • SymmetricDrawCE_WCE4.X86.DAT
      • ColorCE.cs
      • ColorCE.resx
      • curve.cs
      • frmSym.cs
      • frmSym.resx
      • frmSymCE.cs
      • frmSymCE.resx
      • SymmetricDraw.csproj
      • SymmetricDraw.csproj.user
      • SymmetricDrawCE.csdproj
      • SymmetricDrawCE.csdproj.user
      • SymmetryTool.cs
    • Symmetry.sln
    • SymmetryCE.sln
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;

namespace SymmetricDraw
{
	/// <summary>
	/// Summary description for BitmapSaver.
	/// </summary>
	public class BitmapSaver
	{
		/// <summary>
		/// Saves an image (image) at the location defined (szPath). This uses the generic
		/// 24-bit format, so the image is not compressed.
		/// </summary>
		/// <param name="image">The bitmap image to store</param>
		/// <param name="szPath">The path to save at</param>
		static public void SaveBitmapToFile(Image image, string szPath)
		{
			FileStream fs = File.Create(szPath);

			SaveBitmapToStream(image, fs);

			fs.Close();
		}

		/// <summary>
		/// Saves an image (image) at the location defined (szPath). This uses the generic
		/// 24-bit format, so the image is not compressed.
		/// </summary>
		/// <param name="image">The bitmap image to store</param>
		/// <param name="stream">The stream to save to</param>
		static public void SaveBitmapToStream(Image image, Stream stream)
		{
			/* 
			* Sort of from http://msdn.microsoft.com/library/default.asp?url=/library/en-us/gdi/bitmaps_4v1h.asp.
			* The below is hardcoded to support saving a 24-bit bitmap. Slight changes would be made to certain 
			* constants in order to save 16-bit or 256-color (8-bit) or whatever. The resulting file is probably
			* the largest of any image format, which is at the benefit of speed. There are other ways of saving
			* bitmaps (such as using color indexing) which will reduce the bitmap size, but they also add 
			* performance hits. 
			* 
			* ---Data--- ---Bytes---
			* "BM" 0x00-0x01
			* File Size 0x02-0x05
			* Reserved 1 0x06-0x07
			* Reserved 2 0x08-0x09
			* Constant 0x36 0x0A
			* Constant 0x00 0x0B-0x0D
			* Constant 0x28 0x0E (This byte is always 0x28)
			* Constant 0x00 0x0F-0x11 (These bytes are always 0x00)
			* Bitmap Width 0x12-0x15
			* Bitmap Height 0x16-0x19
			* Constant 0x01 0x1A
			* Constant 0x00 0x1B
			* Constant 0x18 0x1C
			* Constant 0x00 0x1D-0x21
			* Image byte size 0x22-0x25
			* Constant 0x00 0x26-0x35
			* Pixels 0x36-Rest 
			* These are 3-byte RGB values for pixels starting at bottom left, moving right. 
			* They are in G-B-R order, and you have to remember to make the full stride (row) a 
			* multiple of 4, meaning that if you have a width of 3, that's only 9 bytes and you
			* have to pad with 3 to round it to the next multiple of 4.
			*/

			// This should probably be done a little more carefully
			Bitmap bm = (Bitmap) image;
			const int BYTES_PER_PIXEL = 3;

			// Need 0x36 bytes for the headers, plus all of the pixel data, so round up to nearest 4
			int nBytes = 0x36 + (bm.Height * ((BYTES_PER_PIXEL * bm.Width) + 0x03) & ~0x03);

			byte[] BitmapData = new byte[nBytes];
			BitmapData[0x00] = (byte) 'B';
			BitmapData[0x01] = (byte) 'M';

			// I'm sure there's a better way to do this but I didn't look up the C# equiv of memcpy
			BitmapData[0x02] = (byte) nBytes;
			BitmapData[0x03] = (byte) (nBytes >> 8);
			BitmapData[0x04] = (byte) (nBytes >> 16);
			BitmapData[0x05] = (byte) (nBytes >> 24);

			BitmapData[0x0A] = 0x36;
			BitmapData[0x0E] = 0x28;

			BitmapData[0x12] = (byte) bm.Width;
			BitmapData[0x13] = (byte) (bm.Width >> 8);
			BitmapData[0x14] = (byte) (bm.Width >> 16);
			BitmapData[0x15] = (byte) (bm.Width >> 24);

			BitmapData[0x16] = (byte) bm.Height;
			BitmapData[0x17] = (byte) (bm.Height >> 8);
			BitmapData[0x18] = (byte) (bm.Height >> 16);
			BitmapData[0x19] = (byte) (bm.Height >> 24);

			BitmapData[0x1A] = 0x01;
			BitmapData[0x1C] = 0x18;

			BitmapData[0x22] = (byte) (nBytes - 0x36);
			BitmapData[0x23] = (byte) ((nBytes - 0x36) >> 8);
			BitmapData[0x24] = (byte) ((nBytes - 0x36) >> 16);
			BitmapData[0x25] = (byte) ((nBytes - 0x36) >> 24);

			// Stripping bitmap from bottom left, moving right through the row, then up to the next row
			int index = 0x36;
			for (int h = bm.Height - 1; h >= 0; h--)
			{
				for (int w = 0; w < bm.Width; w++)
				{
					int c = bm.GetPixel(w, h).ToArgb();
					BitmapData[index++] = (byte) c;
					BitmapData[index++] = (byte) (c >> 8);
					BitmapData[index++] = (byte) (c >> 16);
				}

				// Padding the end of the row 
				// (if I RTFM'd this wouldn't have taken so long to figure out :-) 
				int xtra = (bm.Width * 3) % 4;
				if (xtra != 0)
				{
					index += 4 - xtra;
				}
			}

			// Write the bytes to the stream
			stream.Write(BitmapData, 0, BitmapData.Length);
		}
	}
}

By viewing downloads associated with this article you agree to the Terms of Service and the article's licence.

If a file you wish to view isn't highlighted, and is a text file (not binary), please let us know and we'll add colourisation support for it.

License

This article, along with any associated source code and files, is licensed under The Code Project Open License (CPOL)


Written By
Software Developer Corpria LLC
United States United States
This member has not yet provided a Biography. Assume it's interesting and varied, and probably something to do with programming.

Comments and Discussions