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 | 1734984229 23/12/2024 21:03:49 |
| _ | 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.
Nederlandse vertaling
U hebt gevraagd om deze site in het Nederlands te bezoeken. Voor nu wordt alleen de interface vertaald, maar nog niet alle inhoud.Als je me wilt helpen met vertalingen, is je bijdrage welkom. Het enige dat u hoeft te doen, is u op de site registreren en mij een bericht sturen waarin u wordt gevraagd om u toe te voegen aan de groep vertalers, zodat u de gewenste pagina's kunt vertalen. Een link onderaan elke vertaalde pagina geeft aan dat u de vertaler bent en heeft een link naar uw profiel.
Bij voorbaat dank.
Document heeft de 16/10/2009 gemaakt, de laatste keer de 26/10/2018 gewijzigd
Bron van het afgedrukte document:https://www.gaudry.be/nl/cs-broldev-source-rf-model/drawing/DibToImage.cs.html
De infobrol is een persoonlijke site waarvan de inhoud uitsluitend mijn verantwoordelijkheid is. De tekst is beschikbaar onder CreativeCommons-licentie (BY-NC-SA). Meer info op de gebruiksvoorwaarden en de auteur.