DibToImage.cs
Description du code
DibToImage.cs est un fichier du projet BrolDev.Ce fichier est situé dans /var/www/bin/sniplets/bibliobrol/broldev/src/.
Projet BrolDev : Librairie de composants réutilisables pour les applications BrolDev en CSharp.
Code source ou contenu du fichier
Code c# (DibToImage.cs) (232 lignes)
/* ************************************************************************** Converting memory DIB to .NET 'Bitmap' object EXPERIMENTAL, USE AT YOUR OWN RISK http://dnetmaster.net/ *****************************************************************************/ // // The 'DibToImage' class provides three different methods [Stream/scan0/HBITMAP alive] // // The parameter 'IntPtr dibPtr' is a pointer to // a classic GDI 'packed DIB bitmap', starting with a BITMAPINFOHEADER // // Note, all this methods will use MUCH memory! // (multiple copies of pixel datas) // // Whatever I used, all Bitmap/Image constructors // return objects still beeing backed by the underlying Stream/scan0/HBITMAP. // Thus you would have to keep the Stream/scan0/HBITMAP alive! // // So I tried to make an exact copy/clone of the Bitmap: // But e.g. Bitmap.Clone() doesn't make a stand-alone duplicate. // The working method I used here is : Bitmap copy = new Bitmap( original ); // Unfortunately, the returned Bitmap will always have a pixel-depth of 32bppARGB ! // But this is a pure GDI+/.NET problem... maybe somebody else can help? // // // ---------------------------- // Note, Microsoft should really wrap GDI+ 'GdipCreateBitmapFromGdiDib' in .NET! // This would be very useful! // // There is a : // Bitmap Image.FromHbitmap( IntPtr hbitmap ) // so there is NO reason to not add a: // Bitmap Image.FromGdiDib( IntPtr dibptr ) // // PLEASE SEND EMAIL TO: netfwsdk@microsoft.com // OR mswish@microsoft.com // OR http://register.microsoft.com/mswish/suggestion.asp // ------------------------------------------------------------------------ using System; using System.Drawing; using System.Drawing.Imaging; using System.IO; using System.Runtime.InteropServices; namespace be.gaudry.model.drawing { public class DibToImage { /// <summary> /// Get .NET 'Bitmap' object from memory DIB via stream constructor. /// This should work for most DIBs. /// </summary> /// <param name="dibPtr">Pointer to memory DIB, starting with BITMAPINFOHEADER.</param> public static Bitmap WithStream( IntPtr dibPtr ) { BITMAPINFOHEADER bmi = (BITMAPINFOHEADER) Marshal.PtrToStructure( dibPtr, bmiTyp ); if( bmi.biSizeImage == 0 ) bmi.biSizeImage = ((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * Math.Abs( bmi.biHeight ); if( (bmi.biClrUsed == 0) && (bmi.biBitCount < 16) ) bmi.biClrUsed = 1 << bmi.biBitCount; int dibSize = bmi.biSize + (bmi.biClrUsed * 4) + bmi.biSizeImage; // info + rgb + pixels fh.Size = fhSize + dibSize; // final file size fh.OffBits = fhSize + bmi.biSize + (bmi.biClrUsed * 4); // offset to pixels RawSerializeInto( fh, data ); // serialize BITMAPFILEHEADER into byte[] Marshal.Copy( dibPtr, data, fhSize, dibSize ); // mem-copy DIB into byte[] tmp.Dispose(); tmp = null; stream.Close(); stream = null; data = null; return result; } /// <summary> /// Get .NET 'Bitmap' object from memory DIB via 'scan0' constructor. /// This only works for 16..32 pixel-depth RGB DIBs (no color palette)! /// </summary> /// <param name="dibPtr">Pointer to memory DIB, starting with BITMAPINFOHEADER.</param> public static Bitmap WithScan0( IntPtr dibPtr ) { BITMAPINFOHEADER bmi = (BITMAPINFOHEADER) Marshal.PtrToStructure( dibPtr, bmiTyp ); if( bmi.biCompression != 0 ) PixelFormat fmt = PixelFormat.Undefined; if( bmi.biBitCount == 24 ) fmt = PixelFormat.Format24bppRgb; else if( bmi.biBitCount == 32 ) fmt = PixelFormat.Format32bppRgb; else if( bmi.biBitCount == 16 ) fmt = PixelFormat.Format16bppRgb555; else // we don't support a color palette... int scan0 = ((int) dibPtr) + bmi.biSize + (bmi.biClrUsed * 4); // pointer to pixels int stride = (((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3; // bytes/line if( bmi.biHeight > 0 ) { // bottom-up scan0 += stride * (bmi.biHeight - 1); stride = -stride; } stride, fmt, (IntPtr) scan0 ); // 'tmp' is wired to scan0 (unfortunately) tmp.Dispose(); tmp = null; return result; } /// <summary> /// Get .NET 'Bitmap' object from memory DIB via HBITMAP. /// Uses many temporary copies [huge memory usage]! /// </summary> /// <param name="dibPtr">Pointer to memory DIB, starting with BITMAPINFOHEADER.</param> public static Bitmap WithHBitmap( IntPtr dibPtr ) { BITMAPINFOHEADER bmi = (BITMAPINFOHEADER) Marshal.PtrToStructure( dibPtr, bmiTyp ); if( bmi.biSizeImage == 0 ) bmi.biSizeImage = ((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * Math.Abs( bmi.biHeight ); if( (bmi.biClrUsed == 0) && (bmi.biBitCount < 16) ) bmi.biClrUsed = 1 << bmi.biBitCount; IntPtr img = IntPtr.Zero; int st = GdipCreateBitmapFromGdiDib( dibPtr, pixPtr, ref img ); if( (st != 0) || (img == IntPtr.Zero) ) IntPtr hbitmap; st = GdipCreateHBITMAPFromBitmap( img, out hbitmap, 0 ); if( (st != 0) || (hbitmap == IntPtr.Zero) ) { GdipDisposeImage( img ); } Bitmap tmp = Image.FromHbitmap( hbitmap ); // 'tmp' is wired to hbitmap (unfortunately) tmp.Dispose(); tmp = null; bool ok = DeleteObject( hbitmap ); hbitmap = IntPtr.Zero; st = GdipDisposeImage( img ); img = IntPtr.Zero; return result; } /// <summary> Copy structure into Byte-Array. </summary> private static void RawSerializeInto( object anything, byte[] datas ) { if( rawsize > datas.Length ) GCHandle handle = GCHandle.Alloc( datas, GCHandleType.Pinned ); IntPtr buffer = handle.AddrOfPinnedObject(); Marshal.StructureToPtr( anything, buffer, false ); handle.Free(); } // GDI imports : read MSDN! [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=1)] private class BITMAPFILEHEADER { [MarshalAs( UnmanagedType.ByValArray, SizeConst=2)] public Char[] Type; public Int32 Size; public Int16 reserved1; public Int16 reserved2; public Int32 OffBits; } [StructLayout(LayoutKind.Sequential, Pack=2)] private class BITMAPINFOHEADER { public int biSize; public int biWidth; public int biHeight; public short biPlanes; public short biBitCount; public int biCompression; public int biSizeImage; public int biXPelsPerMeter; public int biYPelsPerMeter; public int biClrUsed; public int biClrImportant; } [DllImport("gdi32.dll", ExactSpelling=true)] private static extern bool DeleteObject( IntPtr obj ); // GDI+ from GdiplusFlat.h : http://msdn.microsoft.com/library/en-us/gdicpp/gdi+/gdi+reference/flatapi.asp [DllImport("gdiplus.dll", ExactSpelling=true)] private static extern int GdipCreateBitmapFromGdiDib( IntPtr bminfo, IntPtr pixdat, ref IntPtr image ); // GpStatus WINGDIPAPI GdipCreateBitmapFromGdiDib( GDIPCONST BITMAPINFO* gdiBitmapInfo, VOID* gdiBitmapData, GpBitmap** bitmap); [DllImport("gdiplus.dll", ExactSpelling=true)] private static extern int GdipCreateHBITMAPFromBitmap( IntPtr image, out IntPtr hbitmap, int bkg ); // GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap( GpBitmap* bitmap, HBITMAP* hbmReturn, ARGB background); [DllImport("gdiplus.dll", ExactSpelling=true)] private static extern int GdipDisposeImage( IntPtr image ); } // class DibToImage } // namespace
Structure et Fichiers du projet
Afficher/masquer...Icône | Nom | Taille | Modification |
Icône | Nom | Taille | Modification |
| _ | Répertoire parent | 0 octets | 1732276503 22/11/2024 12:55:03 |
| _ | colors | 0 octets | 1541007202 31/10/2018 18:33:22 |
| _ | chart | 0 octets | 1541007202 31/10/2018 18:33:22 |
Utilisation de l'explorateur de code
- Navigation :
- Un clic sur une icône de répertoire ouvre ce répertoire pour en afficher les fichiers.
- Lorsque le répertoire en cours ne contient pas de sous-répertoires il est possible de remonter vers le répertoire parent.
- La structure de répertoires en treetable (tableau en forme d'arborescence) n'est plus possibledans cette version.
- Un clic sur une icône de fichier ouvre ce fichier pour en afficher le code avec la coloration syntaxique adaptée en fonction du langage principal utilisé dans le fichier.
- Affichage :
- Il est possible de trier les répertoires ou les fichiers selon certains critères (nom, taille, date).
- Actions :
- Les actions possible sur les fichiers dépendent de vos droits d'utilisateur sur le site. Veuillez activer le mode utilisateur pour activer les actions.
English translation
You have asked to visit this site in English. For now, only the interface is translated, but not all the content yet.If you want to help me in translations, your contribution is welcome. All you need to do is register on the site, and send me a message asking me to add you to the group of translators, which will give you the opportunity to translate the pages you want. A link at the bottom of each translated page indicates that you are the translator, and has a link to your profile.
Thank you in advance.
Document created the 16/10/2009, last modified the 26/10/2018
Source of the printed document:https://www.gaudry.be/en/cs-broldev-source-rf-model/drawing//DibToImage.cs.html
The infobrol is a personal site whose content is my sole responsibility. The text is available under CreativeCommons license (BY-NC-SA). More info on the terms of use and the author.