Доброго времени суток. Подскажите пожалуйста как сделать скриншот экрана(игры) и записать его в JPG. Стандартный PrintScreen делает это некорректно. Получаю образ экрана, могу его записать в BMP, но получаю слишком большой размер файла.
1 прога пишется на Си(блокируется поверхность и по пикселю записывается в файл) 2 mspaint не делает сглаживания, а Photoshop‘а нет
Да, но это не главное, мне нужно сохранить образ экрана в JPG файл. Сейчас скидываю экран размером 800х600 в файл, получаю 960Кб. Это много!
BEGINER, вот код (проверял в VC++2008). Сохраняет в JPG + можно устанавливать степень сжатия. Code: #include "stdafx.h" #include <windows.h> #include <gdiplus.h> #pragma comment (lib, "gdiplus.lib") using namespace Gdiplus; int GetEncoderClsid(WCHAR *format, CLSID *pClsid) { unsigned int num = 0, size = 0; GetImageEncodersSize(&num, &size); if(size == 0) return -1; ImageCodecInfo *pImageCodecInfo = (ImageCodecInfo *)(malloc(size)); if(pImageCodecInfo == NULL) return -1; GetImageEncoders(num, size, pImageCodecInfo); for(unsigned int j = 0; j < num; ++j){ if(wcscmp(pImageCodecInfo[j].MimeType, format) == 0){ *pClsid = pImageCodecInfo[j].Clsid; free(pImageCodecInfo); return j; } } free(pImageCodecInfo); return -1; } int GetScreeny(LPWSTR lpszFilename, ULONG uQuality) // by Napalm { ULONG_PTR gdiplusToken; GdiplusStartupInput gdiplusStartupInput; GdiplusStartup(&gdiplusToken, &gdiplusStartupInput, NULL); HDC hdcScreen = CreateDC(L"DISPLAY", NULL, NULL, NULL); HDC hdcCapture = CreateCompatibleDC(hdcScreen); int nWidth = GetDeviceCaps(hdcScreen, HORZRES), nHeight = GetDeviceCaps(hdcScreen, VERTRES), nBPP = GetDeviceCaps(hdcScreen, BITSPIXEL); LPBYTE lpCapture; BITMAPINFO bmiCapture = { { sizeof(BITMAPINFOHEADER), nWidth, -nHeight, 1, nBPP, BI_RGB, 0, 0, 0, 0, 0, } }; HBITMAP hbmCapture = CreateDIBSection(hdcScreen, &bmiCapture, DIB_PAL_COLORS, (LPVOID *)&lpCapture, NULL, 0); if(!hbmCapture){ DeleteDC(hdcCapture); DeleteDC(hdcScreen); GdiplusShutdown(gdiplusToken); return 1; } int nCapture = SaveDC(hdcCapture); SelectObject(hdcCapture, hbmCapture); BitBlt(hdcCapture, 0, 0, nWidth, nHeight, hdcScreen, 0, 0, SRCCOPY); RestoreDC(hdcCapture, nCapture); DeleteDC(hdcCapture); DeleteDC(hdcScreen); CLSID imageCLSID; Bitmap *pScreenShot = new Bitmap(hbmCapture, (HPALETTE)NULL); EncoderParameters encoderParams; encoderParams.Count = 1; encoderParams.Parameter[0].NumberOfValues = 1; encoderParams.Parameter[0].Guid = EncoderQuality; encoderParams.Parameter[0].Type = EncoderParameterValueTypeLong; encoderParams.Parameter[0].Value = &uQuality; GetEncoderClsid(L"image/jpeg", &imageCLSID); int result = (pScreenShot->Save(lpszFilename, &imageCLSID, &encoderParams) == Ok); delete pScreenShot; DeleteObject(hbmCapture); GdiplusShutdown(gdiplusToken); return result; } int main() { return GetScreeny(L"screeny.jpg", 75); //75-степень сжатия скрина }
Smapt большое спасибо, то что нужно. Вставил в VC6, получил кучу ошибок, добавил SDK их стало меньше, остались такие: Code: f:\program files\microsoft sdks\windows\v6.1\include\winnt.h(3607) : warning C4035: 'ReadPMC' : no return value f:\program files\microsoft sdks\windows\v6.1\include\winnt.h(3637) : warning C4035: 'ReadTimeStampCounter' : no return value f:\program files\microsoft sdks\windows\v6.1\include\wingdi.h(4340) : warning C4068: unknown pragma f:\program files\microsoft sdks\windows\v6.1\include\wingdi.h(4341) : warning C4068: unknown pragma f:\program files\microsoft sdks\windows\v6.1\include\bcrypt.h(112) : error C2485: 'align' : unrecognized extended attribute f:\program files\microsoft sdks\windows\v6.1\include\bcrypt.h(112) : error C2059: syntax error : '(' f:\program files\microsoft sdks\windows\v6.1\include\bcrypt.h(118) : error C2485: 'align' : unrecognized extended attribute f:\program files\microsoft sdks\windows\v6.1\include\bcrypt.h(118) : error C2059: syntax error : '(' F:\project\gdirest\gdirest.cpp(44) : error C2664: 'CreateDCA' : cannot convert parameter 1 from 'unsigned short [8]' to 'const char *' Types pointed to are unrelated; conversion requires reinterpret_cast, C-style cast or function-style cast Error executing cl.exe. gdirest.exe - 5 error(s), 4 warning(s) Как можно их исправить?
Первые 4 варнинга и ошибки у тебя как раз в СДК который ты добавил, так-что разбирайся с ним. А вообще поставь Vc9, я думаю проблемы пропадут.
Поставил Visual C++ 2008 Все равно что-то не нравится, не знаю куда копать Code: Build Log Rebuild started: Project: gdi_prog, Configuration: Debug|Win32 Command Lines Creating temporary file "f:\project\gdi_prog\gdi_prog\Debug\RSP0000078516485732.rsp" with contents [ /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MDd /Yu"stdafx.h" /Fp"Debug\gdi_prog.pch" /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 /c /ZI /TP .\gdi_prog.cpp ] Creating command line "cl.exe @f:\project\gdi_prog\gdi_prog\Debug\RSP0000078516485732.rsp /nologo /errorReport:prompt" Creating temporary file "f:\project\gdi_prog\gdi_prog\Debug\RSP0000088516485732.rsp" with contents [ /Od /D "WIN32" /D "_DEBUG" /D "_CONSOLE" /D "_UNICODE" /D "UNICODE" /Gm /EHsc /RTC1 /MDd /Yc"stdafx.h" /Fp"Debug\gdi_prog.pch" /Fo"Debug\\" /Fd"Debug\vc90.pdb" /W3 /c /ZI /TP .\stdafx.cpp ] Creating command line "cl.exe @f:\project\gdi_prog\gdi_prog\Debug\RSP0000088516485732.rsp /nologo /errorReport:prompt" Creating temporary file "f:\project\gdi_prog\gdi_prog\Debug\TMP0000098516485732.tmp" with contents [ 1 /* CREATEPROCESS_MANIFEST_RESOURCE_ID */ 24 /* RT_MANIFEST */ ".\\Debug\\gdi_prog.exe.embed.manifest" ] Creating command line "rc.exe /fo".\Debug\gdi_prog.exe.embed.manifest.res" f:\project\gdi_prog\gdi_prog\Debug\TMP0000098516485732.tmp" Creating temporary file "f:\project\gdi_prog\gdi_prog\Debug\RSP00000A8516485732.rsp" with contents [ /OUT:"F:\project\gdi_prog\Debug\gdi_prog.exe" /INCREMENTAL /MANIFEST /MANIFESTFILE:"Debug\gdi_prog.exe.intermediate.manifest" /MANIFESTUAC:"level='asInvoker' uiAccess='false'" /DEBUG /PDB:"F:\project\gdi_prog\Debug\gdi_prog.pdb" /SUBSYSTEM:CONSOLE /DYNAMICBASE /NXCOMPAT /MACHINE:X86 kernel32.lib user32.lib gdi32.lib winspool.lib comdlg32.lib advapi32.lib shell32.lib ole32.lib oleaut32.lib uuid.lib odbc32.lib odbccp32.lib ".\Debug\stdafx.obj" ".\Debug\gdi_prog.obj" ".\Debug\gdi_prog.exe.embed.manifest.res" ] Creating command line "link.exe @f:\project\gdi_prog\gdi_prog\Debug\RSP00000A8516485732.rsp /NOLOGO /ERRORREPORT:PROMPT" Creating temporary file "f:\project\gdi_prog\gdi_prog\Debug\RSP00000B8516485732.rsp" with contents [ /out:.\Debug\gdi_prog.exe.embed.manifest /notify_update /manifest .\Debug\gdi_prog.exe.intermediate.manifest ] Creating command line "mt.exe @f:\project\gdi_prog\gdi_prog\Debug\RSP00000B8516485732.rsp /nologo" Output Window Compiling... stdafx.cpp Compiling... gdi_prog.cpp Compiling manifest to resources... Linking... LINK : F:\project\gdi_prog\Debug\gdi_prog.exe not found or not built by the last incremental link; performing full link Embedding manifest... Project : error PRJ0003 : Error spawning 'mt.exe'. Results Build log was saved at "file://f:\project\gdi_prog\gdi_prog\Debug\BuildLog.htm" gdi_prog - 1 error(s), 0 warning(s)
BEGINER, вот твоя ошибка на MSDNe., ну а если вкратце как я понял, могут быть следующие причины: 1) У тебя недостаточно прав для выполнения какой-то операции при компиляции. 2) В настройках неправельно указан путь к каким- либо файлам нужным при компиляции. 3) MT.exe (обычно лежит тут "C:\Program Files\Microsoft Visual Studio 9.0\VC\bin\mt.exe") повреждён? либо его там вообще нету) Куда копать я думаю ясно.
Smapt, большое спасибо, заработало, правда почему-то требует msvcr90d.dll(наверно придется с собой таскать). Буду думать как это прикрутить к существующему проекту на VC6
не мучайся, а просто перекрути проект Vs 6 на 2008-ую, язык и компилятор по сути схожи, там полчасика отсилы потратишь на едит и всё
>>Smapt, большое спасибо, заработало, правда почему-то требует msvcr90d.dll У меня более ранняя версия VS и там, чтобы не просило либ нужно в настройках проекта в Configuration Properties -> General указать Minimize Crt Use in ATL - Yes. Возможно, в следующих версиях отключается аналогичным [ну или схожим образом]. Спасибо за внимание
на сколько я портировал проекты из семерки в девятку, то там встроенный портер есть и вроде шестерку он тоже колбасит. По поводу библы msvcr90d.dll - это из-за динамической линковки. раскручиваем гуглъ как статически линковать проекты.
Спасибо, больше не требует ничего, работает,размер файла 40Кб. Запустил его на другой машине(где нет VC9), стал ругаться "This application has failed to start because the application configuration is incorrect. Reinstalling the application may fix this problem" С чего бы это?
Пытался перекрутить проект с VC6 на VC8. Файл проекта он сконвертировал, а код остался старым. При компиляции показывает более 100 ошибок Больше всего ему не нравились такие строчки где есть "extern " а таких строк у меня сотни Code: файл1.срр int i=0; файл2.срр extern i; //здесь VC8 ругается, что типа int не по умолчанию, хотя VC6 компилит молча
И правильно ругается - все же синтаксическая ошибка) Так что через тот компилер собирать придется, под которым писался код.