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 | 1734971321 23/12/2024 17:28:41 |
| _ | 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.
Version en cache
23/12/2024 17:28:41 Cette version de la page est en cache (à la date du 23/12/2024 17:28:41) afin d'accélérer le traitement. Vous pouvez activer le mode utilisateur dans le menu en haut pour afficher la dernère version de la page.Document créé le 16/10/2009, dernière modification le 26/10/2018
Source du document imprimé : https://www.gaudry.be/cs-broldev-source-rf-model/drawing/DibToImage.cs.html
L'infobrol est un site personnel dont le contenu n'engage que moi. Le texte est mis à disposition sous licence CreativeCommons(BY-NC-SA). Plus d'info sur les conditions d'utilisation et sur l'auteur.