Форум программистов, компьютерный форум, киберфорум
Наши страницы

C++ и WinAPI

Войти
Регистрация
Восстановить пароль
 
 
Рейтинг: Рейтинг темы: голосов - 1, средняя оценка - 4.00
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,507
#1

Как создать скриншот части экрана? - C++ WinAPI

01.05.2013, 22:34. Просмотров 7087. Ответов 38
Метки нет (Все метки)

Можно весь экран заскриншотить потому, что это частный случай части. Но дело не в этом.

Скриншот ведь предполагает какой-то файл иображения, да ведь? *.bmp там или *.jpg, к примеру. Дело в том, что все примеры, на которые я натыкался в инете глукбокомысленно заканчивались вызовом BitBlt, но этот вызов не создаст файла изображения, вот в чём дело!

Ну вот ссыли к примеру:
http://vsokovikov.narod.ru/New_MSDN_API/Bitmaps/captur_image.htm
Как сделать скриншот экрана?
Скриншот экрана

После чего все замолкают- типа дальше догадывайтесь сами.

Нет, сохранение рисунка в каком-то внутреннем формате- это дело хорошее, но пока я не увижу, как это сохранение можно в файл-изображение конвертировать, это для меня пустые звуки.

Спасибо, кто откликнется,
0
Лучшие ответы (1)
Надоела реклама? Зарегистрируйтесь и она исчезнет полностью.
Similar
Эксперт
41792 / 34177 / 6122
Регистрация: 12.04.2006
Сообщений: 57,940
01.05.2013, 22:34
Здравствуйте! Я подобрал для вас темы с ответами на вопрос Как создать скриншот части экрана? (C++ WinAPI):

Как скопировать в буфер обмена скриншот экрана? - C++ WinAPI
День всем добрый! Я сделал программу, которая сохраняет изображение из буфера обмена в .bmp файл. НО! Она работает только если...

Скриншот экрана и его вывод - C++ WinAPI
Задумал написать прикол - делается скриншот экрана и сразу же выводится. Создается ощущение подвисания компьютера (но можно выключить через...

Сделать скриншот экрана / копировать экранную область видеопамяти - C++ WinAPI
Доброго времени суток. Для работы программы необходимо получить копию(скриншот) экрана, с запущенным directX приложением (собственно...

Можно ли на c++ создать программу подобную camstudio (захват видео с экрана)? - C++
Каким образом записывает видео с экрана?Можно ли на c++ сделать что то такое? И что нужно знать чтобы сделать что то подобное помогите

Создать окно приложения размером в одну шестнадцатую площади экрана с заголовком - C++ WinAPI
Создать окно приложения размером в одну шестнадцатую площади экрана с заголовком «Форматирование диска» без кнопок ...

Как сделать скриншот части экрана - Visual Basic .NET
Подскажите пожалуйста как сделать скриншот КУСОЧКА экрана с помощью VB2010? ! Внимание мои знания программиста очень скудны, если можно...

38
Digit@ll
Brainsbreaker
886 / 364 / 31
Регистрация: 01.02.2011
Сообщений: 1,586
01.05.2013, 22:43 #2
Да, а дальше догадывайтесь сами. Велосипед: GetPixel, SetPixel.
0
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,507
01.05.2013, 22:46  [ТС] #3
Я тебе враг разве? Вроде не обзывал тебя нигде.
0
Digit@ll
Brainsbreaker
886 / 364 / 31
Регистрация: 01.02.2011
Сообщений: 1,586
01.05.2013, 23:00 #4
А, да, в последней твоей ссылке об этом есть. Просто когда-то это тоже интересовало. Всё просто.
0
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,507
01.05.2013, 23:01  [ТС] #5
Зачем отписываться без дела? Я же ничего плохого тебе не делал
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
24794 / 16468 / 5076
Регистрация: 22.10.2011
Сообщений: 29,089
Записей в блоге: 5
01.05.2013, 23:53 #6
kravam, ты ж пытался разобраться с OLE? Вот тебе пример с его использованием. Рабочий...
0
Izual
Нарушитель
14 / 119 / 6
Регистрация: 13.11.2012
Сообщений: 1,564
02.05.2013, 01:17 #7
kravam, у вас есть пример взятия принт скрина с всей рабочей области, принт отражает буффер с значениями каждого пикселя, неуж то в интере нет примеров создания BMP JPEG рисунков из буффера(наверно типа BYTE, т.к. 24 битный формат самый распространённый) ?
0
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,507
02.05.2013, 10:43  [ТС] #8
Цитата Сообщение от UI Посмотреть сообщение
kravam, ты ж пытался разобраться с OLE? Вот тебе пример с его использованием. Рабочий...
А нельзя ли как-нибудь по-простому, по нашему, по-сермяжному? Без того, чтобы если хочешь из BitBlt получить графический файл, изучай COM..? Не надо ругаться, вопрос принципиальный.

Не по теме:

Кстати к COM я решил вернуться через некоторое время. Ибо то ли глаз замылился, то ли никто Роджерсона не изучал как я, то ли ещё что. Но сам я понять не могу, а объяснить тоже никто не может.
Агрегация: почему бы в деструкторе внешнего компонента сразу не приравнять количество ссылок на внешний компонент к единице и всё на этом (по Роджерсо


Цитата Сообщение от Izual Посмотреть сообщение
неуж то в интере нет примеров создания BMP JPEG рисунков из буффера(наверно типа BYTE, т.к. 24 битный формат самый распространённый) ?
0
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
24794 / 16468 / 5076
Регистрация: 22.10.2011
Сообщений: 29,089
Записей в блоге: 5
02.05.2013, 11:08 #9
Цитата Сообщение от kravam Посмотреть сообщение
А нельзя ли как-нибудь по-простому, по нашему, по-сермяжному?
Оно тебе надо, заполнять вручную все эти BITMAPFILEHEADER-ы и BITMAPINFOHEADER-ы корректными значениями, получать GetDIBits-ом данные из битмапа и их сохранять в файл? В MSDN есть пример, как это делается: Capturing an Image, до BitBlt (включительно) всё происходит так, как делается по моей первой ссылке, после (сохранение HBITMAP-а) - как по второй.

А теперь - внимание, вопрос на засыпку: зачем? Только чтобы потом гордо заявить, что "у меня программа написана прям на супер-чистом API, и по фиг, что она раздута как дирижабль"? Ты еще на чистом С пиши, угу.
0
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,507
02.05.2013, 17:05  [ТС] #10
Чё зачем? Просто я считаю, что изучать для этой цели COM- это перебор.
0
Убежденный
Ушел с форума
Эксперт С++
15793 / 7230 / 1138
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
02.05.2013, 21:07 #11
Один из способов:

1) Получаем координаты и размер экрана.
Достигается с помощью GetSystemMetrics с параметрами SM_XVIRTUALSCREEN, SM_YVIRTUALSCREEN,
SM_CXVIRTUALSCREEN и SM_CYVIRTUALSCREEN. Если использовать другие параметры, то скриншот
может получиться неполным. Например, если у пользователя подключено два или более мониторов,
картинка будет захвачена только с одного.

2) Получаем контекст устройства экрана (GetDC с NULL), создаем совместимый контекст и битмап
соответствующего размера (CreateCompatibleDC, CreateCompatibleBitmap), "выбираем" битмап (SelectObject) и
зовем функцию BitBlt. К слову, последний аргумент функции BitBlt должен содержать флаг CAPTUREBLT,
иначе в скриншот не попадут полупрозрачные окна (те, которые с расширенным стилем WS_EX_LAYERED).

3) Далее нам поможет функция GetDIBits - она преобразует битмап (HBITMAP) в определенный формат и
"достает" массив пикселей. Там нет ничего сложного, нужно лишь заполнить структуры BITMAPINFO и
BITMAPINFOHEADER. Например, в BITMAPINFOHEADER в поля biWidth и biHeight пишутся размеры битмапа, в
biPlanes указывается 1, в biBitCount - 24 (24 bits per pixel), а в biCompression - BI_RGB.

4) Сохранить полученное изображение в файл можно по-разному.
Например, можно воспользоваться программным интерфейсом GdiPlus - у него есть класс Bitmap с
конструктором, принимающим BITMAPINFO и указатель на массив пикселей, а также encoder-ы,
позволяющие сохранять изображения в разных форматах (BMP, PNG, JPEG и некоторые другие).

Если чуть более подробно - нужно получить список encoder-ов, зарегистрированных в системе (ищите в
MSDN описания функций GetImageEncoders и GetImageEncodersSize), найти среди них нужный по
MIME-типу (например, "image/png"), а затем вызвать метод Bitmap::Save, передав аргументами имя
файла и encoder.
2
volvo
Супер-модератор
Эксперт Pascal/DelphiАвтор FAQ
24794 / 16468 / 5076
Регистрация: 22.10.2011
Сообщений: 29,089
Записей в блоге: 5
02.05.2013, 22:17 #12
Цитата Сообщение от kravam Посмотреть сообщение
я считаю, что изучать для этой цели COM- это перебор.
Ну да, COM-перебор? GDI+ - да ни за что, зачем их вообще только придумали, да? Я дал ссылку на MSDN, там всё делается силами чистейшего WinAPI, чем теперь не устраивает? Длинно? Извините, золотое правило механики не отменял никто. Хотя о чем можно говорить с человеком, выбравшим подобный статус. Он говорит сам за себя...
0
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,507
03.05.2013, 00:08  [ТС] #13
Цитата Сообщение от UI Посмотреть сообщение
GDI+ - да ни за что, зачем их вообще только придумали, да? Я дал ссылку на MSDN, там всё делается силами чистейшего WinAPI, чем теперь не устраивает? Длинно? Извините, золотое правило механики не отменял никто.
сами с собой разговариваете? Я так-то вынес суждение исключительно о COM, и больше ни о чём. Всё остальное- ваши досужие домыслы.

Добавлено через 51 секунду
Цитата Сообщение от UI Посмотреть сообщение
Хотя о чем можно говорить с человеком, выбравшим подобный статус. Он говорит сам за себя...
Не говорите, кто-то заставляет что ли?

Добавлено через 1 час 3 минуты
Убежденный, а вы хорошо разбираетесь во всём этом деле? Чтобы не мутить новую тему не поможете ли вы мне с одним вопросом?

Итак, структура BITMAPINFO:

typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors[1];
} BITMAPINFO, *PBITMAPINFO;
http://msdn.microsoft.com/en-us/libr...=vs.85%29.aspx

А тут перевод:
http://vsokovikov.narod.ru/New_MSDN_API/Bitmaps/str_bitmapinfo.htm

Нас будет интересовать поле
bmiColors
Член структуры bmiColors, содержащий одно из перечисленного ниже:

Массив RGBQUAD. Элементы массива, которые составляют таблицу цветов.

Какие элементы? Какого массива? Конечно, формально
RGBQUAD bmiColors[1];
Это именно объявление массива, спору нет. Но что такое?- этот массив ВСЕГДА будет состоять из одного элемента! То есть это всё равно что было бы объявить так:
typedef struct tagBITMAPINFO {
BITMAPINFOHEADER bmiHeader;
RGBQUAD bmiColors;
} BITMAPINFO, *PBITMAPINFO;
Вот думаю- что они хотели сказать, объявляя массив из одного элемента- ума не приложу... Лезет в голову всякая ерунда, типа- может, размер этого массива не всегда равен 1? Так опять же [1] понимается однозначно...
0
Убежденный
Ушел с форума
Эксперт С++
15793 / 7230 / 1138
Регистрация: 02.05.2013
Сообщений: 11,637
Записей в блоге: 1
Завершенные тесты: 1
03.05.2013, 00:30 #14
Это способ объявления структуры с массивом переменной длины.
В C/C++ нельзя написать ни "array[0]", ни "array[...]".

По поводу данного массива в том же MSDN сказано:
bmiColors

The number of entries in the array depends on the values of the biBitCount and biClrUsed members of the BITMAPINFOHEADER structure.
То есть, там может быть один или более элементов.
1
kravam
быдлокодер
1704 / 891 / 45
Регистрация: 04.06.2008
Сообщений: 5,507
04.05.2013, 03:39  [ТС] #15
Цитата Сообщение от Убежденный Посмотреть сообщение
Это способ объявления структуры с массивом переменной длины.
Да...? Ладно, будем продолжать работать.

Добавлено через 17 часов 13 минут
А как понять "выбрать объект" в...?

То есть я постоянно сталкиваюсь с этим понятием, но хоть убей не могу его сопоставить с чем-то из жизни.

НУ вот например, тут:
http://vsokovikov.narod.ru/New_MSDN_API/D_context/fn_selectobject.htm

"Функция SelectObject выбирает объект в заданный контекст устройства (DC)"

Я пытаюсь как-то внутри себя это как-то понять и не получается.

+++++++++++++++++++++++++++++++++++++++++

Допустим, у меня есть набор предметов- карандаш, тетрадь и книга.

Я могу выбрать один предмет из этих предметов.

Я могу положить выбранный предмет в портфель

Но я не могу выбрать тетрадку в портфель, вот в чём дело! "Выбрать тетрадку в портфель" (или "выбрать один из предметов в портфель")- это что-то уму непостижимое. Так вообще никто не говорит. В портфель кладут, помещают, запихивают. НО НЕ ВЫБИРАЮТ!

+++++++++++++++++++++++++++++++++++++++++

Тем не менее "выбрать объект в заданный контекст устройства" имеет смысл. Но какой? И я не придрался к словам, я не понимаю, что за этими словами стоит!
0
04.05.2013, 03:39
MoreAnswers
Эксперт
37091 / 29110 / 5898
Регистрация: 17.06.2006
Сообщений: 43,301
04.05.2013, 03:39
Привет! Вот еще темы с ответами:

Как сделать скриншот экрана (просто скрин полного экрана) и сохранить изображение в определённую папку? - C#
Как сделать скриншот экрана (просто скрин полного экрана) и сохранить изображение в определённую папку? Программа без кнопок просто...

Как сделать скриншот экрана? - C# WPF
Как сделать скриншот экрана (допустим, 200 на 300px, по координатам x: 150, y: 20) и поместить его в image?

Как снять скриншот экрана? - Lazarus
и поместить его в jpg или bmp

Как сделать скриншот экрана? - C (СИ)
1. Программа через равные промежутки времени (2...5 сек) должна делать скриншот и сохранять его в любом формате, файл постоянно...


Искать еще темы с ответами

Или воспользуйтесь поиском по форуму:
15
Ответ Создать тему
Опции темы

КиберФорум - форум программистов, компьютерный форум, программирование
Powered by vBulletin® Version 3.8.9
Copyright ©2000 - 2018, vBulletin Solutions, Inc.