Image.FromHbitmap(IntPtr hbitmap)
От: Аноним  
Дата: 17.11.10 12:30
Оценка:
Помогите пожалуйста.

Есть всем знакомый метод:
public static Bitmap System.Drawing.Image.FromHbitmap(IntPtr hbitmap)


где hbitmap это дескриптор точечного рисунка GDI.

Вопрос в следующем: что представляет из себя этот дескриптор(может есть какая нибудь структура на которую он указывает)?

Вопрос был вызван тем что если использовать следующею функцию для WPF:

        private static System.Windows.Media.Imaging.BitmapSource loadBitmap(System.Drawing.Bitmap source)
        {
            IntPtr ip = source.GetHbitmap();
            System.Windows.Media.Imaging.BitmapSource bs = null;
            try
            {
                bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ip,
                   IntPtr.Zero, System.Windows.Int32Rect.Empty,
                   System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
            }
            finally
            {
                GDI32.DeleteDC(ip);
            }

            return bs;
        }


и попытаться отобразить скриншот рабочего стола, то отображаются только иконки и кнопки: закрыть, развернуть и свернуть, а все остальное — белый фон. В случае Image.FromHbitmap(IntPtr hbitmap) все отображается корректно.
Re: Image.FromHbitmap(IntPtr hbitmap)
От: Clickmaker Россия http://relaxander.webest.net/
Дата: 17.11.10 13:05
Оценка:
А> IntPtr ip = source.GetHbitmap();

А> finally

А> {
А> GDI32.DeleteDC(ip);
А> }

??? Получаем как HBITMAP, а удаляем как HDC?
Re[2]: Image.FromHbitmap(IntPtr hbitmap)
От: Аноним  
Дата: 17.11.10 13:43
Оценка: :)
Здравствуйте, Clickmaker, Вы писали:

C>??? Получаем как HBITMAP, а удаляем как HDC?


Да

            [DllImport("gdi32.dll")]
            public static extern bool DeleteDC(IntPtr hDC);
Re[2]: Image.FromHbitmap(IntPtr hbitmap)
От: Аноним  
Дата: 17.11.10 13:51
Оценка:
Здравствуйте, Clickmaker, Вы писали:

А>> IntPtr ip = source.GetHbitmap();


А>> finally

А>> {
А>> GDI32.DeleteDC(ip);
А>> }

C>??? Получаем как HBITMAP, а удаляем как HDC?


Вот примеры
Пример1
Пример2
Вроде так делается — все от туда брал
Re[3]: Image.FromHbitmap(IntPtr hbitmap)
От: Clickmaker Россия http://relaxander.webest.net/
Дата: 17.11.10 13:54
Оценка:
Здравствуйте, Аноним, Вы писали:

А>Здравствуйте, Clickmaker, Вы писали:


А>>> IntPtr ip = source.GetHbitmap();


А>>> finally

А>>> {
А>>> GDI32.DeleteDC(ip);
А>>> }

C>>??? Получаем как HBITMAP, а удаляем как HDC?


А>Вот примеры

А>Пример1
А>Пример2
А>Вроде так делается — все от туда брал

вообще-то там DeleteObject
Re: Image.FromHbitmap(IntPtr hbitmap)
От: Clickmaker Россия http://relaxander.webest.net/
Дата: 17.11.10 15:15
Оценка:
А>скриншот рабочего стола, то отображаются только иконки и кнопки: закрыть, развернуть и свернуть

который где? в bitmapSource?
чьи там иконки и кнопки?
Re[4]: Image.FromHbitmap(IntPtr hbitmap)
От: Аноним  
Дата: 18.11.10 07:30
Оценка:
Здравствуйте, Clickmaker, Вы писали:


C>вообще-то там DeleteObject


Да-да. спасибо))) а я думаю почему память кушается
Но проблема с отображением все равно осталась.
Re[2]: Image.FromHbitmap(IntPtr hbitmap)
От: Аноним  
Дата: 18.11.10 07:43
Оценка:
Здравствуйте, Clickmaker, Вы писали:


А>>скриншот рабочего стола, то отображаются только иконки и кнопки: закрыть, развернуть и свернуть


C>который где? в bitmapSource?

C>чьи там иконки и кнопки?

У меня есть такие методы:

        public static System.Windows.Media.Imaging.BitmapSource CaptureScreenWPF()
        {
            return CaptureWindowWPF(User32.GetDesktopWindow());
        }

        public static System.Windows.Media.Imaging.BitmapSource CaptureWindowWPF(IntPtr handle)
        {
            IntPtr hdcSrc = User32.GetWindowDC(handle);
            User32.RECT windowRect = new User32.RECT();
            User32.GetWindowRect(handle, ref windowRect);
            int width = windowRect.right - windowRect.left;
            int height = windowRect.bottom - windowRect.top;
            IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
            IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
            IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
            GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
            GDI32.SelectObject(hdcDest, hOld);
            GDI32.DeleteDC(hdcDest);
            User32.ReleaseDC(handle, hdcSrc);
            System.Windows.Media.Imaging.BitmapSource bs = null;
            try
            {
                bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ip,
                   IntPtr.Zero, System.Windows.Int32Rect.Empty,
                   System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
            }
            finally
            {
                GDI32.DeleteObject(ip);
            }
            return bs;                     
        }

        private class GDI32
        {
            public const int SRCCOPY = 0x00CC0020; 
            [DllImport("gdi32.dll")]
            public static extern bool BitBlt(IntPtr hObject, int nXDest, int nYDest, int nWidth, int nHeight, IntPtr hObjectSource,
                int nXSrc, int nYSrc, int dwRop);
            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleBitmap(IntPtr hDC, int nWidth, int nHeight);
            [DllImport("gdi32.dll")]
            public static extern IntPtr CreateCompatibleDC(IntPtr hDC);
            [DllImport("gdi32.dll")]
            public static extern bool DeleteDC(IntPtr hDC);
            [DllImport("gdi32.dll")]
            public static extern bool DeleteObject(IntPtr hObject);
            [DllImport("gdi32.dll")]
            public static extern IntPtr SelectObject(IntPtr hDC, IntPtr hObject);
        }

        private class User32
        {
            [StructLayout(LayoutKind.Sequential)]
            public struct RECT
            {
                public int left;
                public int top;
                public int right;
                public int bottom;
            }

            [DllImport("user32.dll")]
            public static extern IntPtr GetDesktopWindow();
            [DllImport("user32.dll")]
            public static extern IntPtr GetWindowDC(IntPtr hWnd);
            [DllImport("user32.dll")]
            public static extern IntPtr ReleaseDC(IntPtr hWnd, IntPtr hDC);
            [DllImport("user32.dll")]
            public static extern IntPtr GetWindowRect(IntPtr hWnd, ref RECT rect);
        }


вообщем когда я получаю скриншот при вызове метода CaptureScreenWPF() — получаю почему то его частично. т.е. если открыты окна, то на картинке отображаются кнопки: закрыть, развернуть и свернуть — т.е. правый верхний угол. и иконка окна(левый верхний угол). и еще отображаются иконки на панели инструментов. Я бы выложил картинку, но не знаю как... Я думаю если вы скопируете эти методы и попытаетесь отобразить рабочий стол — то увидите этот эффект.

Кстати если сначала получить картинку в виде System.Drawing.Bitmap, а потом использовать метод

        private static System.Windows.Media.Imaging.BitmapSource loadBitmap(System.Drawing.Bitmap source)
        {
            IntPtr ip = source.GetHbitmap();
            System.Windows.Media.Imaging.BitmapSource bs = null;
            try
            {
                bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ip,
                   IntPtr.Zero, System.Windows.Int32Rect.Empty,
                   System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
            }
            finally
            {
                GDI32.DeleteObject(ip);
            }

            return bs;
        }

то отображается весь рабочий стол. но мне так не пойдет — слишком много преобразований(сначала Bitmap, а потом BitmapSource)

PS: работаю под WinXP SP3
Re[3]: Image.FromHbitmap(IntPtr hbitmap)
От: Clickmaker Россия http://relaxander.webest.net/
Дата: 18.11.10 08:58
Оценка:
этот код не скомпилиться.
что такое ip в CaptureWindowWPF?
Re[4]: Image.FromHbitmap(IntPtr hbitmap)
От: Аноним  
Дата: 18.11.10 09:15
Оценка:
Здравствуйте, Clickmaker, Вы писали:

C>этот код не скомпилиться.

C>что такое ip в CaptureWindowWPF?

сорри. за место ip нужно поставить hBitmap. что-то я еще не проснулся...
Re[5]: Image.FromHbitmap(IntPtr hbitmap)
От: Clickmaker Россия http://relaxander.webest.net/
Дата: 18.11.10 10:20
Оценка:
Да, там наблюдается некоторая избирательность.
Не виден системный текст на таскбаре и, похоже, 16-цветные иконки у некоторых приложений.

а насчет "если сначала получить картинку в виде System.Drawing.Bitmap" — каким образом?
Re[6]: Image.FromHbitmap(IntPtr hbitmap)
От: Аноним  
Дата: 18.11.10 10:39
Оценка:
Здравствуйте, Clickmaker, Вы писали:

C>Да, там наблюдается некоторая избирательность.

C>Не виден системный текст на таскбаре и, похоже, 16-цветные иконки у некоторых приложений.

Не знаешь как это исправить?

C>а насчет "если сначала получить картинку в виде System.Drawing.Bitmap" — каким образом?



Я делаю так:

        public static System.Windows.Media.Imaging.BitmapSource CaptureScreenWPF()
        {
            return CaptureWindowWPF(User32.GetDesktopWindow());
        }

        public static Image CaptureWindow(IntPtr handle)
        {
            IntPtr hdcSrc = User32.GetWindowDC(handle);
            User32.RECT windowRect = new User32.RECT();
            User32.GetWindowRect(handle, ref windowRect);
            int width = windowRect.right - windowRect.left;
            int height = windowRect.bottom - windowRect.top;
            IntPtr hdcDest = GDI32.CreateCompatibleDC(hdcSrc);
            IntPtr hBitmap = GDI32.CreateCompatibleBitmap(hdcSrc, width, height);
            IntPtr hOld = GDI32.SelectObject(hdcDest, hBitmap);
            GDI32.BitBlt(hdcDest, 0, 0, width, height, hdcSrc, 0, 0, GDI32.SRCCOPY);
            GDI32.SelectObject(hdcDest, hOld);
            GDI32.DeleteDC(hdcDest);
            User32.ReleaseDC(handle, hdcSrc);
            Image img = Image.FromHbitmap(hBitmap);
            GDI32.DeleteObject(hBitmap);
            return img;
        }

        public static System.Windows.Media.Imaging.BitmapSource CaptureWindowWPF(IntPtr handle)
        {
            return loadBitmap((Bitmap)CaptureWindow(handle));
        }

        private static System.Windows.Media.Imaging.BitmapSource loadBitmap(System.Drawing.Bitmap source)
        {
            IntPtr ip = source.GetHbitmap();
            System.Windows.Media.Imaging.BitmapSource bs = null;
            try
            {
                bs = System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(ip,
                   IntPtr.Zero, System.Windows.Int32Rect.Empty,
                   System.Windows.Media.Imaging.BitmapSizeOptions.FromEmptyOptions());
            }
            finally
            {
                GDI32.DeleteObject(ip);
            }

            return bs;
        }
Re[7]: Image.FromHbitmap(IntPtr hbitmap)
От: Clickmaker Россия http://relaxander.webest.net/
Дата: 18.11.10 11:14
Оценка:
А>Не знаешь как это исправить?

Похоже, альфа-канал мешает

CaptureWindowWPF()

FormatConvertedBitmap cb = new FormatConvertedBitmap();
cb.BeginInit();
cb.Source = bs;
cb.DestinationFormat = PixelFormats.Rgb24;
cb.EndInit();
return cb;
Re[8]: Image.FromHbitmap(IntPtr hbitmap)
От: Аноним  
Дата: 18.11.10 11:33
Оценка:
Здравствуйте, Clickmaker, Вы писали:

C>Похоже, альфа-канал мешает


C>CaptureWindowWPF()


C>FormatConvertedBitmap cb = new FormatConvertedBitmap();

C>cb.BeginInit();
C>cb.Source = bs;
C>cb.DestinationFormat = PixelFormats.Rgb24;
C>cb.EndInit();
C>return cb;

Точно! Спасибо!
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.