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 octets1732518418 25/11/2024 08:06:58
| _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.

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.