
Что же я перепробовал:
1. Метод компонента doSaveDIB (сохраняет кадр в файл) для последующей загрузки картинки из файла и переворота. Однако это придётся делать несколько раз в секунду, что сильно замедлит программу.
2. Метод doEditCopy - помещает кадр в буфер обмена. Однако не очень хорошо, если программа без ведома пользователя будет что-то помещать в буфер - тогда пользователь не сможет с ним работать.
3. Может быть, есть какие-то другие методы, не реализованные в WebCam? Порывшись на сайте https://learn.microsoft.com/en-us/windows/win32/multimedia/wm-cap-edit-copy, я ничего подходящего не нашёл. Да, есть какая-то колбэк-функция при получении очередного кадры с камеры, но ничего не описано, где именно там хранится картинка. Соответственно, в интернетах я по этому поводу тоже толком ничего не нашёл. Не выдаёт этот функционал картинку в поток/переменную, а только её отрисовывает!
4. Дальше уже пошли опыты в IC. Опробована фукнция
BitBlt(bmp.Canvas.Handle, 0, 0, 320, 240, GetDC(h), 0, 0, SRCCOPY);
5. Были мысли, может, методу doSaveDIB подсунуть имя какого-нибудь виртуального файла, на самом деле указывающего на участок памяти, но в сети я так и не нашёл толкового способа это сделать.
6. Спросил ИИ: ГПТ, copilot, replit... Видели бы вы, ЧТО они мне навыдавали! Какие-то несуществующие функции типа capGetFrame (существует только [url=http://learn.microsoft.com/en-us/windows/win32/api/vfw/nf-vfw-capgrabframe]capGrabFrame[/url], она позволяет получать один кадр с камеры в окно просмотра),
SendMessage(h, WM_CAP_COPY, 0, LPARAM(Bmp.Handle))
7. Сунулся было в DirectX - читал, что там расширенные возможности видеозахвата, но кода там на неделю разбираться для такой мелочи, как разворот картинки.
...
Решение нашлось, отуда не ждали. Есть такой стиль окон - WS_EX_LAYOUTRTL, он отражает справа налево само окно. Отражение выполняется самой виндой, достаточно установить этот стиль - и она сама будет разворачивать окно вместе с картинкой!
Add(WebCam,1803333,497,406)
{
RefreshRate=200
FileDIB="a.bmp"
FileVideo="cam.avi"
Point(doVideoSource)
Point(doVideoFormat)
Point(doVideoCompression)
Point(doSaveDIB)
link(WinHandle,14074503:Handle,[])
}
Add(Button,7768292,378,350)
{
Left=5
Top=35
Caption="Source"
link(onClick,1803333:doVideoSource,[(454,356)(454,426)])
}
Add(Button,14395040,371,392)
{
Left=5
Top=55
Caption="Format"
link(onClick,1803333:doVideoFormat,[(450,398)(450,433)])
}
Add(Button,7859332,371,434)
{
Left=5
Top=75
Caption="Compress"
link(onClick,1803333:doVideoCompression,[])
}
Add(Image,14074503,504,350)
{
Left=65
Top=5
Width=320
Height=263
Point(Handle)
Point(doRefresh)
}
Add(Hub,5680976,420,287)
{
link(onEvent1,1803333:doDisConnect,[(471,293)(471,419)])
link(onEvent2,1803333:doConnect,[(466,300)(466,412)])
}
Add(Button,11636729,378,287)
{
Left=5
Top=10
Caption="On"
link(onClick,5680976:doEvent1,[])
}
Add(InlineCode,14009132,497,483)
{
WorkPoints=#1:a|
EventPoints=#5:onBmp|
DataPoints=#8:dtHandle|
Code=#42://Отражение картинки с камеры по вертикали|15:unit HiAsmUnit;|0:|9:interface|0:|38:uses windows,kol,Share,Debug,hiWebCam;|0:|24:var rtl:boolean = false;|0:|4:type|28: THiAsmClass = class(TDebug)|10: private|9: public|23: dtHandle:THI_Event;|20: onBmp:THI_Event;|42: procedure a(var dt:TData; index:word);|0:|5: end;|0:|14:implementation|0:|24:procedure THiAsmClass.a;|30:var h:longword; //bmp:PBitmap;|34:const WS_EX_LAYOUTRTL = $00400000;|5:begin|31: h := ToIntegerEvent(dtHandle);|29: //Bmp := NewBitmap(640,480);|14: {xy.x := 100;|13: xy.y := 100;|55: SendMessage(h, WM_CAP_SET_SCROLL, 0, longint(@(xy)));}|81: //SendMessage(h, WM_CAP_SET_CALLBACK_FRAME, 0, longint(@FrameCallbackFunction));|43: //SendMessage(h, WM_CAP_GRAB_FRAME, 0, 0);|70: //BitBlt(bmp.Canvas.Handle, 0, 0, 320, 240, GetDC(h), 0, 0, SRCCOPY);|33: //Bmp.Canvas.Handle := GetDC(h);|0:|97: if rtl then SetWindowLong(h, GWL_EXSTYLE, GetWindowLong(h, GWL_EXSTYLE) and not WS_EX_LAYOUTRTL)|87: else SetWindowLong(h, GWL_EXSTYLE, GetWindowLong(h, GWL_EXSTYLE) or WS_EX_LAYOUTRTL);|16: rtl := not rtl;|26: //_hi_OnEvent(onBmp,Bmp);|4:end;|0:|4:end.|
link(dtHandle,1803333:Handle,[])
}
Add(Button,12790683,378,483)
{
Left=5
Top=100
Caption="RTL"
link(onClick,14009132:a,[])
}
Редактировалось 6 раз(а), последний 2025-03-29 23:40:49