コード例 #1
0
        /// <summary>
        /// Get managed BitmapSource from a DIB provided as a low level windows hadle
        ///
        /// Notes:
        /// Data is copied from the source so the windows handle can be saftely discarded
        /// even when the BitmapSource is in use.
        ///
        /// Only a subset of possible DIB forrmats is supported.
        ///
        /// </summary>
        /// <param name="dibHandle"></param>
        /// <returns>A copy of the image in a managed BitmapSource </returns>
        ///
        public static BitmapSource FormHDib(IntPtr dibHandle)
        {
            BitmapSource bs     = null;
            IntPtr       bmpPtr = IntPtr.Zero;
            bool         flip   = true; // vertivcally flip the image

            try {
                bmpPtr = Win32.GlobalLock(dibHandle);
                Win32.BITMAPINFOHEADER bmi = new Win32.BITMAPINFOHEADER();
                Marshal.PtrToStructure(bmpPtr, bmi);

                if (bmi.biSizeImage == 0)
                {
                    bmi.biSizeImage = (uint)(((((bmi.biWidth * bmi.biBitCount) + 31) & ~31) >> 3) * bmi.biHeight);
                }

                int palettSize = 0;

                if (bmi.biClrUsed != 0)
                {
                    throw new NotSupportedException("DibToBitmap: DIB with pallet is not supported");
                }

                // pointer to the beginning of the bitmap bits
                IntPtr pixptr = (IntPtr)((int)bmpPtr + bmi.biSize + palettSize);

                // Define parameters used to create the BitmapSource.
                PixelFormat pf = PixelFormats.Default;
                switch (bmi.biBitCount)
                {
                case 32:
                    pf = PixelFormats.Bgr32;
                    break;

                case 24:
                    pf = PixelFormats.Bgr24;
                    break;

                case 8:
                    pf = PixelFormats.Gray8;
                    break;

                case 1:
                    pf = PixelFormats.BlackWhite;
                    break;

                default:       // not supported
                    throw new NotSupportedException("DibToBitmap: Can't determine picture format (biBitCount=" + bmi.biBitCount + ")");
                    // break;
                }
                int    width      = bmi.biWidth;
                int    height     = bmi.biHeight;
                int    stride     = (int)(bmi.biSizeImage / height);
                byte[] imageBytes = new byte[stride * height];

                //Debug: Initialize the image with random data.
                //Random value = new Random();
                //value.NextBytes(rawImage);

                if (flip)
                {
                    for (int i = 0, j = 0, k = (height - 1) * stride; i < height; i++, j += stride, k -= stride)
                    {
                        Marshal.Copy(((IntPtr)((int)pixptr + j)), imageBytes, k, stride);
                    }
                }
                else
                {
                    Marshal.Copy(pixptr, imageBytes, 0, imageBytes.Length);
                }

                int xDpi = (int)Math.Round(bmi.biXPelsPerMeter * 2.54 / 100); // pels per meter to dots per inch
                int yDpi = (int)Math.Round(bmi.biYPelsPerMeter * 2.54 / 100);

                // Create a BitmapSource.
                bs = BitmapSource.Create(width, height, xDpi, yDpi, pf, null, imageBytes, stride);
            } catch (Exception ex) {
                string msg = ex.Message;
            }
            finally {
                // cleanup
                if (bmpPtr != IntPtr.Zero)   // locked sucsessfully
                {
                    Win32.GlobalUnlock(dibHandle);
                }
            }
            return(bs);
        }