Witam serdecznie!
Czy wie ktos z forumowiczow w jaki sposob rozwiazac zapisywanie do avi (nie koniecznie z kodekiem)
aktualnego obrazu wyswietlanego na pulpicie?
0
0
Moze robic 25 razy na sekunde zrzut ekranu i zapisywac do pliku? Mozna by tez pomyslec o jakims uproszczeniu, zeby np. zapisywac tylko zmiany obrazu, a nie Ciag podobnych klatek.
0
Nic prostszego: jednofunkcyjny program zapisujący desktop razem z kursorem do avi.
Z kodekiem XVID ustawionym jak w komentażu - przy WXGA | 5 FPS | 1minuta = 4.2MB z bardzo dobrą jakością. Ustawiony format kompresora można zapisać by nie ustawiać go za każdym razem.
#include "stdafx.h"
#include <vfw.h>
#pragma comment(lib,"Vfw32.lib")
int APIENTRY _tWinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,LPTSTR lpCmdLine,int nCmdShow)
{
int src_w = GetSystemMetrics(SM_CXSCREEN);
int src_h = GetSystemMetrics(SM_CYSCREEN);
int video_w = src_w;
int video_h = src_h;
HRESULT hr;
IAVIFile *avifile;
CoInitialize(0);
DeleteFile(TEXT("c:\\capture.avi"));
hr = AVIFileOpen(&avifile, TEXT("c:\\capture.avi"), OF_WRITE | OF_CREATE, NULL);
if (hr)
{
CoUninitialize();
return MessageBox(0, TEXT("AVIFileOpen failed"),0,0);
}
HDC dcDesktop = GetDC(0);
HDC cdc = CreateCompatibleDC(dcDesktop);
BITMAPINFOHEADER bihdr;
ZeroMemory(&bihdr, sizeof(bihdr));
bihdr.biSize = sizeof(bihdr);
bihdr.biWidth = video_w;
bihdr.biHeight = video_h;
bihdr.biPlanes = 1;
bihdr.biBitCount = 24;
int biSizeImage = video_w * video_h * 3; // later compressor->Write
void *pBits;
HGDIOBJ bmp = SelectObject(cdc, CreateDIBSection(dcDesktop, (BITMAPINFO*)&bihdr, DIB_RGB_COLORS, &pBits, 0, 0));
AVISTREAMINFOW strhdr;
ZeroMemory(&strhdr, sizeof(strhdr));
strhdr.fccType = streamtypeVIDEO;
strhdr.dwScale = 1;
strhdr.dwRate = 5; // 5 klatek na sekundę
SetRect(&strhdr.rcFrame, 0, 0, bihdr.biWidth, bihdr.biHeight);
IAVIStream *pstream;
if (avifile->CreateStream(&pstream, &strhdr))
{
MessageBox(0, TEXT("CreateStream failed"),0,0);
}
else
{
// add compression filter (XVID MPEG4: Single Pass; Quantizer:4; Profile:unrestricted; QualityPreset:realtime)
IAVIStream *compressor;
AVICOMPRESSOPTIONS DefaultOpts;
ZeroMemory(&DefaultOpts, sizeof(DefaultOpts)); // no compression
// load saved options
AVICOMPRESSOPTIONS *psavedopts = &DefaultOpts;
//LoadCompressOptions(TEXT("c:\\capture.options"), &psavedopts);
if (AVISaveOptions(0,ICMF_CHOOSE_KEYFRAME|ICMF_CHOOSE_DATARATE,1,&pstream,&psavedopts))
// SaveCompressOptions(psavedopts, "c:\\capture.options");
hr = AVIMakeCompressedStream(&compressor, pstream, psavedopts, NULL);
if (!hr)
{
AVISaveOptionsFree(1, &psavedopts);
//if (psavedopts != DefaultOpts)
// delete psavedopts;
hr = compressor->SetFormat(0, &bihdr, sizeof(bihdr));
// ograniczenie czasu filmu - jedna minuta
int NumFrames = strhdr.dwRate * /*seconds*/60 * /*minutes*/1;
for (int frameno=0; frameno<NumFrames; frameno++)
{
//SetConsoleTitle(sprint(frameno*100/NumFrames,"%"));
if (video_w==src_w && video_h==src_h)
BitBlt(cdc, 0, 0, video_w, video_h, dcDesktop, 0, 0, SRCCOPY|CAPTUREBLT);
else
//
StretchBlt(cdc, 0, 0, video_w, video_h, dcDesktop, 0, 0, src_w, src_h, SRCCOPY|CAPTUREBLT);
// rysuj kursor ?
CURSORINFO cursor;
cursor.cbSize = sizeof(cursor);
if (GetCursorInfo(&cursor) && (cursor.flags == CURSOR_SHOWING))
{
DrawIcon(cdc, cursor.ptScreenPos.x, cursor.ptScreenPos.y, cursor.hCursor);
}
// trial info?
TextOut(cdc,10,10,TEXT("zdjełano w cccp"), 15);
hr = compressor->Write(frameno, 1, pBits, biSizeImage, AVIIF_KEYFRAME, NULL, NULL);
if (hr)
{
MessageBox(0, TEXT("Write failed"),0,0);
break;
}
Sleep(10); // prymitywne
}
compressor->Release();
}
pstream->Release();
}
avifile->Release();
DeleteObject(SelectObject(cdc, bmp));
DeleteDC(cdc);
ReleaseDC(0, dcDesktop);
CoUninitialize();
return 0;
}