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

  1. /* **************************************************************************
  2.   Converting memory DIB to .NET 'Bitmap' object
  3.   EXPERIMENTAL, USE AT YOUR OWN RISK
  4.   http://dnetmaster.net/
  5. *****************************************************************************/
  6. //
  7. // The 'DibToImage' class provides three different methods [Stream/scan0/HBITMAP alive]
  8. //
  9. // The parameter 'IntPtr dibPtr' is a pointer to
  10. // a classic GDI 'packed DIB bitmap', starting with a BITMAPINFOHEADER
  11. //
  12. // Note, all this methods will use MUCH memory!
  13. // (multiple copies of pixel datas)
  14. //
  15. // Whatever I used, all Bitmap/Image constructors
  16. // return objects still beeing backed by the underlying Stream/scan0/HBITMAP.
  17. // Thus you would have to keep the Stream/scan0/HBITMAP alive!
  18. //
  19. // So I tried to make an exact copy/clone of the Bitmap:
  20. // But e.g. Bitmap.Clone() doesn't make a stand-alone duplicate.
  21. // The working method I used here is : Bitmap copy = new Bitmap( original );
  22. // Unfortunately, the returned Bitmap will always have a pixel-depth of 32bppARGB !
  23. // But this is a pure GDI+/.NET problem... maybe somebody else can help?
  24. //
  25. //
  26. // ----------------------------
  27. // Note, Microsoft should really wrap GDI+ 'GdipCreateBitmapFromGdiDib' in .NET!
  28. // This would be very useful!
  29. //
  30. // There is a :
  31. // Bitmap Image.FromHbitmap( IntPtr hbitmap )
  32. // so there is NO reason to not add a:
  33. // Bitmap Image.FromGdiDib( IntPtr dibptr )
  34. //
  35. // PLEASE SEND EMAIL TO: netfwsdk@microsoft.com
  36. // OR mswish@microsoft.com
  37. // OR http://register.microsoft.com/mswish/suggestion.asp
  38. // ------------------------------------------------------------------------
  39.  
  40. using System;
  41. using System.Drawing;
  42. using System.Drawing.Imaging;
  43. using System.IO;
  44. using System.Runtime.InteropServices;
  45.  
  46.  
  47. namespace be.gaudry.model.drawing
  48. {
  49.  
  50. public class DibToImage
  51. {
  52.  
  53.  
  54. /// <summary>
  55. /// Get .NET 'Bitmap' object from memory DIB via stream constructor.
  56. /// This should work for most DIBs.
  57. /// </summary>
  58. /// <param name="dibPtr">Pointer to memory DIB, starting with BITMAPINFOHEADER.</param>
  59. public static Bitmap WithStream( IntPtr dibPtr )
  60. {
  61. BITMAPFILEHEADER fh = new BITMAPFILEHEADER();
  62. Type bmiTyp = typeof(BITMAPINFOHEADER);
  63. BITMAPINFOHEADER bmi = (BITMAPINFOHEADER) Marshal.PtrToStructure( dibPtr, bmiTyp );
  64. if( bmi.biSizeImage == 0 )
  65. bmi.biSizeImage = ((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * Math.Abs( bmi.biHeight );
  66. if( (bmi.biClrUsed == 0) && (bmi.biBitCount < 16) )
  67. bmi.biClrUsed = 1 << bmi.biBitCount;
  68.  
  69. int fhSize = Marshal.SizeOf( typeof(BITMAPFILEHEADER) );
  70. int dibSize = bmi.biSize + (bmi.biClrUsed * 4) + bmi.biSizeImage; // info + rgb + pixels
  71.  
  72. fh.Type = new Char[] { 'B', 'M' }; // "BM"
  73. fh.Size = fhSize + dibSize; // final file size
  74. fh.OffBits = fhSize + bmi.biSize + (bmi.biClrUsed * 4); // offset to pixels
  75.  
  76. byte[] data = new byte[ fh.Size ]; // file-sized byte[]
  77. RawSerializeInto( fh, data ); // serialize BITMAPFILEHEADER into byte[]
  78. Marshal.Copy( dibPtr, data, fhSize, dibSize ); // mem-copy DIB into byte[]
  79.  
  80. MemoryStream stream = new MemoryStream( data ); // file-sized stream
  81. Bitmap tmp = new Bitmap( stream ); // 'tmp' is wired to stream (unfortunately)
  82. Bitmap result = new Bitmap( tmp ); // 'result' is a copy (stand-alone)
  83. tmp.Dispose(); tmp = null;
  84. stream.Close(); stream = null; data = null;
  85. return result;
  86. }
  87.  
  88.  
  89.  
  90. /// <summary>
  91. /// Get .NET 'Bitmap' object from memory DIB via 'scan0' constructor.
  92. /// This only works for 16..32 pixel-depth RGB DIBs (no color palette)!
  93. /// </summary>
  94. /// <param name="dibPtr">Pointer to memory DIB, starting with BITMAPINFOHEADER.</param>
  95. public static Bitmap WithScan0( IntPtr dibPtr )
  96. {
  97. Type bmiTyp = typeof(BITMAPINFOHEADER);
  98. BITMAPINFOHEADER bmi = (BITMAPINFOHEADER) Marshal.PtrToStructure( dibPtr, bmiTyp );
  99. if( bmi.biCompression != 0 )
  100. throw new ArgumentException( "Invalid bitmap format (non-RGB)", "BITMAPINFOHEADER.biCompression" );
  101.  
  102. PixelFormat fmt = PixelFormat.Undefined;
  103. if( bmi.biBitCount == 24 )
  104. fmt = PixelFormat.Format24bppRgb;
  105. else if( bmi.biBitCount == 32 )
  106. fmt = PixelFormat.Format32bppRgb;
  107. else if( bmi.biBitCount == 16 )
  108. fmt = PixelFormat.Format16bppRgb555;
  109. else // we don't support a color palette...
  110. throw new ArgumentException( "Invalid pixel depth (<16-Bits)", "BITMAPINFOHEADER.biBitCount" );
  111.  
  112. int scan0 = ((int) dibPtr) + bmi.biSize + (bmi.biClrUsed * 4); // pointer to pixels
  113. int stride = (((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3; // bytes/line
  114. if( bmi.biHeight > 0 )
  115. { // bottom-up
  116. scan0 += stride * (bmi.biHeight - 1);
  117. stride = -stride;
  118. }
  119. Bitmap tmp = new Bitmap( bmi.biWidth, Math.Abs( bmi.biHeight ),
  120. stride, fmt, (IntPtr) scan0 ); // 'tmp' is wired to scan0 (unfortunately)
  121. Bitmap result = new Bitmap( tmp ); // 'result' is a copy (stand-alone)
  122. tmp.Dispose(); tmp = null;
  123. return result;
  124. }
  125.  
  126.  
  127.  
  128.  
  129.  
  130. /// <summary>
  131. /// Get .NET 'Bitmap' object from memory DIB via HBITMAP.
  132. /// Uses many temporary copies [huge memory usage]!
  133. /// </summary>
  134. /// <param name="dibPtr">Pointer to memory DIB, starting with BITMAPINFOHEADER.</param>
  135. public static Bitmap WithHBitmap( IntPtr dibPtr )
  136. {
  137. Type bmiTyp = typeof(BITMAPINFOHEADER);
  138. BITMAPINFOHEADER bmi = (BITMAPINFOHEADER) Marshal.PtrToStructure( dibPtr, bmiTyp );
  139. if( bmi.biSizeImage == 0 )
  140. bmi.biSizeImage = ((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * Math.Abs( bmi.biHeight );
  141. if( (bmi.biClrUsed == 0) && (bmi.biBitCount < 16) )
  142. bmi.biClrUsed = 1 << bmi.biBitCount;
  143.  
  144. IntPtr pixPtr = new IntPtr( (int) dibPtr + bmi.biSize + (bmi.biClrUsed * 4) ); // pointer to pixels
  145.  
  146. IntPtr img = IntPtr.Zero;
  147. int st = GdipCreateBitmapFromGdiDib( dibPtr, pixPtr, ref img );
  148. if( (st != 0) || (img == IntPtr.Zero) )
  149. throw new ArgumentException( "Invalid bitmap for GDI+", "IntPtr dibPtr" );
  150.  
  151. IntPtr hbitmap;
  152. st = GdipCreateHBITMAPFromBitmap( img, out hbitmap, 0 );
  153. if( (st != 0) || (hbitmap == IntPtr.Zero) )
  154. {
  155. GdipDisposeImage( img );
  156. throw new ArgumentException( "can't get HBITMAP with GDI+", "IntPtr dibPtr" );
  157. }
  158.  
  159. Bitmap tmp = Image.FromHbitmap( hbitmap ); // 'tmp' is wired to hbitmap (unfortunately)
  160. Bitmap result = new Bitmap( tmp ); // 'result' is a copy (stand-alone)
  161. tmp.Dispose(); tmp = null;
  162. bool ok = DeleteObject( hbitmap ); hbitmap = IntPtr.Zero;
  163. st = GdipDisposeImage( img ); img = IntPtr.Zero;
  164. return result;
  165. }
  166.  
  167.  
  168.  
  169. /// <summary> Copy structure into Byte-Array. </summary>
  170. private static void RawSerializeInto( object anything, byte[] datas )
  171. {
  172. int rawsize = Marshal.SizeOf( anything );
  173. if( rawsize > datas.Length )
  174. throw new ArgumentException( " buffer too small ", " byte[] datas " );
  175. GCHandle handle = GCHandle.Alloc( datas, GCHandleType.Pinned );
  176. IntPtr buffer = handle.AddrOfPinnedObject();
  177. Marshal.StructureToPtr( anything, buffer, false );
  178. handle.Free();
  179. }
  180.  
  181.  
  182.  
  183. // GDI imports : read MSDN!
  184.  
  185. [StructLayout(LayoutKind.Sequential, CharSet=CharSet.Ansi, Pack=1)]
  186. private class BITMAPFILEHEADER
  187. {
  188. [MarshalAs( UnmanagedType.ByValArray, SizeConst=2)]
  189. public Char[] Type;
  190. public Int32 Size;
  191. public Int16 reserved1;
  192. public Int16 reserved2;
  193. public Int32 OffBits;
  194. }
  195.  
  196. [StructLayout(LayoutKind.Sequential, Pack=2)]
  197. private class BITMAPINFOHEADER
  198. {
  199. public int biSize;
  200. public int biWidth;
  201. public int biHeight;
  202. public short biPlanes;
  203. public short biBitCount;
  204. public int biCompression;
  205. public int biSizeImage;
  206. public int biXPelsPerMeter;
  207. public int biYPelsPerMeter;
  208. public int biClrUsed;
  209. public int biClrImportant;
  210. }
  211.  
  212. [DllImport("gdi32.dll", ExactSpelling=true)]
  213. private static extern bool DeleteObject( IntPtr obj );
  214.  
  215.  
  216.  
  217. // GDI+ from GdiplusFlat.h : http://msdn.microsoft.com/library/en-us/gdicpp/gdi+/gdi+reference/flatapi.asp
  218.  
  219. [DllImport("gdiplus.dll", ExactSpelling=true)]
  220. private static extern int GdipCreateBitmapFromGdiDib( IntPtr bminfo, IntPtr pixdat, ref IntPtr image );
  221. // GpStatus WINGDIPAPI GdipCreateBitmapFromGdiDib( GDIPCONST BITMAPINFO* gdiBitmapInfo, VOID* gdiBitmapData, GpBitmap** bitmap);
  222.  
  223. [DllImport("gdiplus.dll", ExactSpelling=true)]
  224. private static extern int GdipCreateHBITMAPFromBitmap( IntPtr image, out IntPtr hbitmap, int bkg );
  225. // GpStatus WINGDIPAPI GdipCreateHBITMAPFromBitmap( GpBitmap* bitmap, HBITMAP* hbmReturn, ARGB background);
  226.  
  227. [DllImport("gdiplus.dll", ExactSpelling=true)]
  228. private static extern int GdipDisposeImage( IntPtr image );
  229.  
  230. } // class DibToImage
  231.  
  232. } // namespace

Structure et Fichiers du projet

Afficher/masquer...


Répertoires contenus dans /var/www/bin/sniplets/bibliobrol/broldev/src/model/drawing/ 
IcôneNomTailleModification
IcôneNomTailleModification
| _ Répertoire parent0 octets1714373994 29/04/2024 08:59:54
| _colors0 octets1541007202 31/10/2018 18:33:22
| _chart0 octets1541007202 31/10/2018 18:33:22
Fichiers contenus dans /var/www/bin/sniplets/bibliobrol/broldev/src/model/drawing/ 
IcôneNomTailleModificationAction
IcôneNomTailleModificationAction
Afficher le fichier .cs|.csIconExtractor.cs5.18 Ko31/10/2018 18:33:08-refusé-
Afficher le fichier .cs|.csImageHelper.cs7.19 Ko31/10/2018 18:33:08-refusé-
Afficher le fichier .cs|.csBrolImage.cs6.29 Ko31/10/2018 18:33:08-refusé-
Afficher le fichier .cs|.csDibToImage.cs8.83 Ko31/10/2018 18:33:08-refusé-

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.

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.