前一段时间遇到了这个问题,我的地图想保存成一个bitmap文件,但在CF1.0下BitMap类没有一个方法可以把当前的Bitmap保存成一个bmp文件.上网查了一些
资料在opennetcf的论坛里找到一篇文章:
http://www.opennetcf.org/forums/topic.asp?TOPIC_ID=385
有详细的介绍,好东西自然收录一份。^_^
用起来也比较方便,只是保存下来的bmp文件个头不小.呵呵.
把主要保存代码内容摘出来:
-----------------------------------------------
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
namespace SaveThisImage
{
/// <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);
}
}
}
using System;
using System.Drawing;
using System.IO;
using System.Runtime.InteropServices;
namespace SaveThisImage
{
/// <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);
}
}
}