Ищу библиотеку для захвата изображения в заданном окне и записи в avi файл.
Желательно на базе WinAPI (AVIStream* функций), чтоб полегковеснее.
Здравствуйте, Abyx, Вы писали:
A>Ищу библиотеку для захвата изображения в заданном окне и записи в avi файл.
A>Желательно на базе WinAPI (AVIStream* функций), чтоб полегковеснее.
библиотеку не нашел, похоже придется писать велосипед =\
если вдруг кому понадобится — вот прототип
#include <cassert>
#include <Windows.h>
#include <Vfw.h>
#pragma comment(lib, "Vfw32.lib")
struct avi_config
{
DWORD fccType;
DWORD fccHandler;
DWORD dwQuality;
};
avi_config ask_avi_config(HWND hwnd = 0, const char* title = "Choose codec")
{
// AVISaveOptions requires a stream so we can't use it here
avi_config cfg;
COMPVARS compvars = {0};
compvars.cbSize = sizeof(compvars);
ICCompressorChoose(hwnd, ICMF_CHOOSE_ALLCOMPRESSORS, nullptr, nullptr, &compvars, (LPSTR)title);
cfg.fccType = compvars.fccType;
cfg.fccHandler = compvars.fccHandler;
cfg.dwQuality = compvars.lQ;
ICCompressorFree(&compvars);
return cfg;
}
void record_avi(const avi_config& cfg)
{
auto cx = 301; // test of unaligned data
auto cy = 200;
auto bpp = 3;
auto pitch = (cx * bpp + 3) & ~3; // line width in bytes, aligned upto 4
auto fps = 10;
auto frameSize = pitch * cy;
BYTE* frameBuf = new BYTE[frameSize];
PAVIFILE pfile;
PAVISTREAM uncompressedStream;
PAVISTREAM compressedStream;
HRESULT hr;
CoInitialize(0);
AVIFileInit();
hr = AVIFileOpenA(&pfile, "test.avi", OF_CREATE | OF_WRITE, nullptr);
assert(hr == S_OK);
AVISTREAMINFO info = {0};
info.fccType = streamtypeVIDEO;
info.dwScale = 1;
info.dwRate = fps;
info.dwSuggestedBufferSize = frameSize;
info.rcFrame.right = cx;
info.rcFrame.bottom = cy;
info.dwQuality = ~0u;
hr = AVIFileCreateStream(pfile, &uncompressedStream, &info);
assert(hr == S_OK);
AVICOMPRESSOPTIONS options = {0};
options.fccType = cfg.fccType;
options.fccHandler = cfg.fccHandler;
options.dwQuality = cfg.dwQuality;
hr = AVIMakeCompressedStream(&compressedStream, uncompressedStream, &options, nullptr);
assert(hr == S_OK);
BITMAPINFOHEADER bmpInfo = {0}; // probably only 6 or 7 first fields are used
bmpInfo.biSize = sizeof(bmpInfo);
bmpInfo.biWidth = cx;
bmpInfo.biHeight = cy;
bmpInfo.biPlanes = 1;
bmpInfo.biBitCount = WORD(bpp * 8);
bmpInfo.biCompression = BI_RGB;
hr = AVIStreamSetFormat(compressedStream, 0, &bmpInfo, bmpInfo.biSize);
assert(hr == S_OK);
// write some frames (moving blue line, like [/ ] -> [ /])
// (x = 0, y = 0) point is at bottom-left corner, so image it bottom-up: bmpInfo.biHeight > 0
ZeroMemory(frameBuf, frameSize);
for(auto frameIdx = 0; frameIdx != 300; ++frameIdx)
{
auto it = frameBuf;
for(auto y = 0; y != cy; ++y)
{
for(auto x = 0; x != cx; ++x)
{
assert(it < frameBuf + frameSize);
it[0] = x == (frameIdx + y / 4) % cx ? 0xFF - BYTE(y) : 0;
it += bpp;
}
it += (pitch - cx * bpp); // skip alignment
}
hr = AVIStreamWrite(compressedStream, frameIdx, 1, frameBuf, frameSize, 0, nullptr, nullptr);
assert(hr == S_OK);
}
// cleanup
delete[] frameBuf;
AVIStreamRelease(compressedStream);
AVIStreamRelease(uncompressedStream);
auto refs = AVIFileRelease(pfile);
assert(refs == 0);
AVIFileExit();
CoUninitialize();
}
int main()
{
auto aviCfg = ask_avi_config();
record_avi(aviCfg);
}