Форум программистов «Весельчак У»
  *
Добро пожаловать, Гость. Пожалуйста, войдите или зарегистрируйтесь.
Вам не пришло письмо с кодом активации?

  • Рекомендуем проверить настройки временной зоны в вашем профиле (страница "Внешний вид форума", пункт "Часовой пояс:").
  • У нас больше нет рассылок. Если вам приходят письма от наших бывших рассылок mail.ru и subscribe.ru, то знайте, что это не мы рассылаем.
   Начало  
Наши сайты
Помощь Поиск Календарь Почта Войти Регистрация  
 
Страниц: [1]   Вниз
  Печать  
Автор Тема: Вывод рисунка из окна в файл  (Прочитано 8316 раз)
0 Пользователей и 1 Гость смотрят эту тему.
onic777
Интересующийся

md
Offline Offline
Пол: Мужской

« : 25-10-2016 20:21 » 

Добрый день!

В программе есть окно, в котором программно построено некоторое изображение!
Про окно известно int iwidth, int iheigh, HDC hDCWnd.
Как корректно это окно скопировать в Bitmap с помощью BitBlt, а затем вывести с помощью Save в файл jpeg???

Помогите новичку в Visual C++, а то несколько запутался в hwnd & hdc  Не надо

Onic777


Добавлено через 19 минут и 49 секунд:
В дополнению к вопросу напишу что сделано. Пишется функция вывода содержимого окна в jpeg файл


static bool SaveToJPEG (System::String ^ SaveFileName, int iwidth, int iheigh, HDC hDCWnd)
{

    HDC hDCMem = CreateCompatibleDC(hDCWnd);
    HBITMAP hBmp = CreateCompatibleBitmap(hDCWnd, iwidth, iheigh);   
    HGDIOBJ hTmp = SelectObject(hDCMem, hBmp);
    REZ = BitBlt(hDCMem, 0, 0, iwidth, iheigh, hDCWnd, 0, 0, SRCCOPY);

    // ВОПРОС В ТОМ, КАК КОРРЕКТНО НАПИСАТЬ СЛЕДУЮЩУЮ СТРОКУ !!!         
    hDCMem Не понял  Save(SaveFileName, System::Drawing::Imaging::ImageFormat::Jpeg);
         
    SelectObject(hDCMem, hTmp);
    DeleteObject(hDCMem);
    ReleaseDC(hWnd, hDCWnd);
   return true;
}
« Последнее редактирование: 25-10-2016 20:41 от onic777 » Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #1 : 26-10-2016 04:35 » 

HBITMAP hBmp  в данном случае пристёгнут к HDC hDCMem. Поэтому, когда рисуем на hDCMem, результат "оседает" на hBmp
Далее нужно танцевать примерно отсюда
https://msdn.microsoft.com/library/windows/desktop/dd144850

Кстати, не забывай также и hBmp релизнуть, когда он будет уже не нужен, а то мало ли, память потечёт )
« Последнее редактирование: 26-10-2016 04:37 от Алексей++ » Записан

onic777
Интересующийся

md
Offline Offline
Пол: Мужской

« Ответ #2 : 26-10-2016 09:11 » 

Добрый день!

А чуток подробней нельзя??? А то вообще все как в тумане!!! После 22 лет работы с Borland...
Указанная Вами ссылка посылает на функцию GetBitmapBits. But This function is provided only for compatibility with 16-bit versions of Windows! I Must Use GetDIBits!

int GetDIBits(
  _In_    HDC          hdc,      // Это получается HDC на мое исходное окно hDCWnd
  _In_    HBITMAP      hbmp, // Это совместимы Bitmap

  _In_    UINT         uStartScan, // Это совсем не понятно! Пересылка идет строками??? Это начало строки? Т.е. применительно к моему случаю это Х=0???

  _In_    UINT         cScanLines, // Тогда получается что это строки, т.е. длина строки??? Т.е. ширина окна???

  _Out_   LPVOID       lpvBits, // Функия сама открывает линейный буфер с объемом iwidth * iheigh * 3 и пише тайты подряд первого пикселя (X=0,Y=0) ,три бита цвета, затем (x=1,y=0) и тд Это указатель на буфер?

Могу ли о открыть двумерный битмап с размерами моего окна и писать в него???

System::Drawing::Bitmap ^ bm = gcnew Bitmap(iwidth, iheigh);
int GetDIBits(hTmp, hBmp, 0, iheigh, bm, null, DIB_RGB_COLORS);

Последнюю строчку компилятор не пропускает hTmp не нравится, и null тоже!
Помогите пожалуйста...

 
 
  _Inout_ LPBITMAPINFO lpbi,
  _In_    UINT         uUsage
);

Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #3 : 26-10-2016 09:22 » new

onic777, я и сам на Qt уже подсел и в такие дебри давно не лазил )

возможно, и GetDIBits.  Указывать надо hDCMem и hBmp, я думаю.

uStartScan =0
cScanLines = высота битмапа (iheigh )

размер lpvBits  - зависит от переданного и заполненного lpbi (структура lpbi  описывает, в каком виде вернуть битмап, поэтому она обязательна, я полагаю)
uUsage  - укажи DIB_RGB_COLORS








Добавлено через 2 минуты и 53 секунды:
и там приписочка - если lpvBits  передать null , то внутри функции будет заполнена структура по указателю lpbi - то есть, актуальными параметрами битмапа hBmp

Добавлено через 2 минуты и 10 секунд:
то есть, функция действует по разному (в зависимости от параметров)
1) если lpvBits ==0 , то функция заполняет lpbi
2) если lpvBits!= 0 , то функция использует lpbi  и uUsage   и заполняет lpvBits
« Последнее редактирование: 26-10-2016 09:28 от Алексей1153 » Записан

onic777
Интересующийся

md
Offline Offline
Пол: Мужской

« Ответ #4 : 28-10-2016 20:25 » 

Всем привет и спасибо за помощь!

Делается все следующим образом:

Сперва формируется изображение например всего экрана:
static Bitmap^   My_Image;

static void CaptureExport::CaptureScene(HWND hWndSrc)
{
RECT windowRect = RECT();
GetWindowRect(hWndSrc, &windowRect);
iwidth  = windowRect.right  - windowRect.left;
iheight = windowRect.bottom - windowRect.top;

HDC      hdcSrc = GetWindowDC(GetDesktopWindow());               
HDC      hdcDest = CreateCompatibleDC(hdcSrc); // Create compatible memory device context(DC)
HBITMAP hBitmap = CreateCompatibleBitmap(hdcSrc, iwidth, iheight);   // Create compatible bitmap
HGDIOBJ hOld = SelectObject(hdcDest, hBitmap); // Selects an object into the specified device context (DC)
                           // New object replaces the previous andhas the same type
BitBlt(hdcDest, 0, 0,iwidth,iheight,hdcSrc, windowRect.left, windowRect.top, SRCCOPY);
// Copy from Scene into Compatible Bitmap

SelectObject(hdcDest, hOld); // Restore Selection
DeleteDC(hdcDest); // Clear compatible memory device context(DC)
CreateLogicalPalette(hdcSrc);

My_Image = System::Drawing::Image::FromHbitmap((IntPtr)hBitmap, (IntPtr)Scene_Palette);
DeleteObject(hBitmap); // Free up the Compatible Bitmap object
}

Затем выбранная область выводится в выбранный фомат файла:
My_Image->Save(SaveFileName, System::Drawing::Imaging::ImageFormat::Jpeg);

Вот и все!
Все Успехов!

Regards,
Onic777
Записан
Алексей++
глобальный и пушистый
Глобальный модератор

ru
Offline Offline
Сообщений: 13


« Ответ #5 : 29-10-2016 05:34 » 

не забудь в конце процедуры подчистить все созданные хендлы. У тебя пропущено:
https://msdn.microsoft.com/en-us/library/windows/desktop/dd144947(v=vs.85).aspx

ReleaseDC(hdcSrc)

Записан

Страниц: [1]   Вверх
  Печать  
 

Powered by SMF 1.1.21 | SMF © 2015, Simple Machines