[win] захват изображения
От: Abyx Россия  
Дата: 04.05.11 06:21
Оценка:
Ищу библиотеку для захвата изображения в заданном окне и записи в avi файл.
Желательно на базе WinAPI (AVIStream* функций), чтоб полегковеснее.
In Zen We Trust
Re: [win] захват изображения
От: fdn721  
Дата: 04.05.11 08:59
Оценка: -1
Здравствуйте, Abyx, Вы писали:

A>Ищу библиотеку для захвата изображения в заданном окне и записи в avi файл.

A>Желательно на базе WinAPI (AVIStream* функций), чтоб полегковеснее.

А сами то вы что будете писать?
С Delphi недавно перешли?
Re[2]: [win] захват изображения
От: Abyx Россия  
Дата: 04.05.11 09:22
Оценка: +1
Здравствуйте, fdn721, Вы писали:

F>А сами то вы что будете писать?

код который решает задачу, а не велосипеды

F>С Delphi недавно перешли?

перешел, но очень давно.
и идеи "да я сам на голом винапи и Си всё напишу" меня давно уже не вдохновляют
In Zen We Trust
Re: [win] захват изображения
От: Abyx Россия  
Дата: 06.05.11 10:37
Оценка: 2 (1)
Здравствуйте, 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);
}
In Zen We Trust
 
Подождите ...
Wait...
Пока на собственное сообщение не было ответов, его можно удалить.