|
|
| Please spread the word if you like this content! |
|
|
|
|
| |
Ok, after pulling out my hair trying to generate thumbnails from device-independent bitmaps stored by a CArchive in an "old" MFC program, I finally got help here at the workplace on this. I must say I could not find this easily with much Googling, ergo I'm gonna post this up here with comments for anyone else out there looking for the same thing. Please suggest any updations to comments and / or code, if you see the need... NOTE: This code has been updated. Look here for it.
// our BITMAPINFOHEADER struct, as per gdi // use LayoutKind to make sure data is marshalled as we've laid it out [StructLayout(LayoutKind.Sequential)] public struct BITMAPINFOHEADER { public uint biSize; public int biWidth; public int biHeight; public ushort biPlanes; public ushort biBitCount; public uint biCompression; public uint biSizeImage; public int biXPelsPerMeter; public int biYPelsPerMeter; public uint biClrUsed; public uint biClrImportant; public void Init() { biSize = (uint)Marshal.SizeOf(this); } }
public static Bitmap BitmapFromDIB(MemoryStream dib) { // get byte array of device independent bitmap byte[] dibBytes = dib.ToArray();
// get the handle for the byte array and "pin" that memory (i.e. prevent garbage collector from // gobbling it up right away)... GCHandle hdl = GCHandle.Alloc(dibBytes, GCHandleType.Pinned);
// marshal our data into a BITMAPINFOHEADER struct per Win32 definition of BITMAPINFOHEADER BITMAPINFOHEADER dibHdr = (BITMAPINFOHEADER)Marshal.PtrToStructure(hdl.AddrOfPinnedObject(), typeof(BITMAPINFOHEADER));
// go ahead and release the "pin" from our handle on that memory hdl.Free();
// If the target device does not have one plane, or we're working with a bitmap other than a // non-compressed (BI_RGB) bitmap, we're not gonna work woith it if (dibHdr.biPlanes != 1 || dibHdr.biCompression != 0) return null;
// we need to know beforehand the pixel-depth of our bitmap PixelFormat fmt = PixelFormat.Format24bppRgb; switch (dibHdr.biBitCount) { case 32: fmt = PixelFormat.Format32bppRgb; break; case 24: fmt = PixelFormat.Format24bppRgb; break; case 16: fmt = PixelFormat.Format16bppRgb555; break; default: return null; }
// prepare for our output bitmap Bitmap bmp = new Bitmap(dibHdr.biWidth, dibHdr.biHeight, fmt);
// load our "empty" bitmap into memory and lock it for writing in the format we specified BitmapData bd = bmp.LockBits(new Rectangle(0, 0, bmp.Width, bmp.Height), ImageLockMode.WriteOnly, fmt);
// marshal our device independent bitmap data over to our output bitmap Marshal.Copy(dibBytes, Marshal.SizeOf(dibHdr), bd.Scan0, bd.Stride * bd.Height);
// we're done marshalling, so release our bitmapdata lock bmp.UnlockBits(bd);
// DIB data is upside-down for some reason, so flip it bmp.RotateFlip(RotateFlipType.RotateNoneFlipY);
// return our bitmap return bmp; }
~simon
posted @ Monday, November 24, 2008 9:18 AM
Print
Archives
- September, 2010 (1)
- August, 2010 (3)
- July, 2010 (5)
- May, 2010 (1)
- April, 2010 (1)
- December, 2009 (1)
- November, 2009 (1)
- October, 2009 (2)
- September, 2009 (2)
- August, 2009 (2)
- July, 2009 (1)
- June, 2009 (1)
- May, 2009 (3)
- April, 2009 (4)
- March, 2009 (3)
- February, 2009 (3)
- January, 2009 (3)
- December, 2008 (1)
- November, 2008 (2)
- October, 2008 (4)
- September, 2008 (1)
- August, 2008 (1)
- July, 2008 (3)
- June, 2008 (3)
- May, 2008 (4)
- April, 2008 (1)
- March, 2008 (2)
- February, 2008 (1)
- January, 2008 (3)
- December, 2007 (3)
- September, 2007 (1)
- August, 2007 (1)
- June, 2007 (1)
- May, 2007 (2)
- February, 2007 (1)
- December, 2006 (2)
- November, 2006 (4)
- September, 2006 (1)
- August, 2006 (1)
- May, 2006 (3)
Post Categories
| |
| 29 | 30 | 31 | 1 | 2 | 3 | 4 | | 5 | 6 | 7 | 8 | 9 | 10 | 11 | | 12 | 13 | 14 | 15 | 16 | 17 | 18 | | 19 | 20 | 21 | 22 | 23 | 24 | 25 | | 26 | 27 | 28 | 29 | 30 | 1 | 2 | | 3 | 4 | 5 | 6 | 7 | 8 | 9 |
|