Вверх ↑
Этот топик читают: Гость
Ответов: 1931
Рейтинг: 174
#1: 2025-03-29 23:36:20 ЛС | профиль | цитата
В качестве веб-камеры используется камера заднего вида автомобиля, а она внутри себя переворачивает картинку справа налево. Естественно, неплохо было бы её перевернуть обратно, но стандартный компонент WebCam такой функцией не обладает. Вроде бы решение очевидно: получить картинку с камеры и уже графическими компонентами перевернуть её обратно, но вот тут возникла проблема: WebCam не выдаёт картинку в поток, он только отрисовывает её на указанном элементе.


Что же я перепробовал:
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);
, где h - это указатель на окно видеозахвата, получаемый с нижней точки компонента WebCam, а bmp - созданная временная картинка. Способ рабочий, да вот только исходный (т.е. отражённый справа налево) кадр при этом должен оставаться видимым на форме, иначе ничего не работает. А зачем отображать исходное, неправильное изображение?
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))
(это сообщение копирует кадр в буфер обмена, оно и используется в doEditCopy, но LParam там совсем не используется!). В общем, почти всё нерабочее, для моей wели не подошло ничего.
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
карма: 9
1
Голосовали:zhorik5
Ответов: 8946
Рейтинг: 824
#2: 2025-03-30 10:07:22 ЛС | профиль | цитата
3042, отлично, спасибо! (Чего только нет в Windos )
Смешивал предыдущий кадр с текущим через IC, по точкам в цикле, успевал при 30 кадров/сек.
карма: 19

0
Ответов: 187
Рейтинг: 4
#3: 2025-04-01 13:02:27 ЛС | профиль | цитата
С моей камерой зеленый экран с первым типом сжатия. С вторым -черный экран. Хотя странно - камера много лет выпускается logitech c270.
карма: 1

0
Ответов: 1931
Рейтинг: 174
#4: 2025-04-02 11:28:28 ЛС | профиль | цитата
strannik_nebes, кодеки vfw установлены? В Mega Codec Pack они есть.



Редактировалось 1 раз(а), последний 2025-04-02 11:33:36
карма: 9
0
Ответов: 187
Рейтинг: 4
#5: 2025-04-03 10:50:44 ЛС | профиль | цитата
3042, стоят. Отображаются в этой утилите с правами администратора. Устанавливал MegaPack. Без изменений. Настройки по умолчанию

Редактировалось 1 раз(а), последний 2025-04-03 10:51:45
карма: 1

0
Ответов: 1931
Рейтинг: 174
#6: 2025-04-03 21:21:15 ЛС | профиль | цитата
А в стандартном приложении windows "Камера" картинка с этой камеры есть?
карма: 9
0
Ответов: 187
Рейтинг: 4
#7: 2025-04-04 08:05:25 ЛС | профиль | цитата
3042, да.Только что проверил. Проблем с камерой не было никогда.
карма: 1

0
Ответов: 1931
Рейтинг: 174
#8: 2025-04-05 12:55:44 ЛС | профиль | цитата
strannik_nebes, тогда попробуйте через directX: https://hiasm.bbtalk.me/viewtopic.php?id=372#p744. Там у andrestudio компонент, в нём можно получать картинку с камеры в поток и потом уже разворачивать и делать всё что угодно.
карма: 9
1
Голосовали:strannik_nebes
Ответов: 187
Рейтинг: 4
#9: 2025-04-07 09:02:59 ЛС | профиль | цитата
3042, тоже не работает. Делал по инструкции в окне. Ошибок никаких не выдает в логе. Черный экран видео.
Установка Direct x не решила проблему.

Редактировалось 2 раз(а), последний 2025-04-07 09:11:47
карма: 1

0
9
Сообщение
...
Прикрепленные файлы
(файлы не залиты)