Модератор: Mikle
1) старый - capCreateCaptureWindow (ненадёжный, зачастую выдаёт пустой экран вместо камеры, а если и включается - всегда тянет, изображение меняется ступенчато; к тому же, при каждом подключении выдаёт неубиваемое окно выбора камеры, которое захлопнуть мне удалось только сторонне запущенным скриптом AHK, т.к. программка VB с WM_CLOSE или SendKeys закрывает его как-то не так, как нужно для корректной работы камеры, а WM_QUIT закрывает вместе с окном самой программы)
'Каждый новый кадр камеры вызывает:
Private Sub Cam_EventOfCamera(ByVal pBmp As Long, ByVal nTyp As Long)
size& = Cam.GetImgLen(1)
hData& = GlobalAlloc(2&, size)
pData& = GlobalLock(hData)
CopyMemory ByVal pData, ByVal pBmp, size
GlobalUnlock hData
SprBack.LoadFromData hData ' Метод LoadFromData добавил на основе LoadFromBytes с форума Arthur02 http://bbs.vbstreets.ru/viewtopic.php?f=6&t=56557
SprBack.PaintToDevice hDC
End Sub
Private Sub Form_Load()
Cam.OpenCapDev 0, 0
End Sub
Vova_2581 писал(а):Что-то не то вы делаете. Если в системе одна камера, то никакого запроса... не будет. "Черный экран" зависит от метода сжатия, оно меняется в настройках.
С.Т. писал(а):VbCreateThread превосходно справляется, но если подключить сторонние DLL со своей многопоточностью (например, BASS.dll для работы звуком и подключения к MIDI), программа начинает падать.
The trick писал(а):Если тебе необходимо сделать чтобы в потоке просто получалось изображение с "тормознутой" камеры (сам почти никогда не имел дело с камерами мб там есть асинхронные механизмы),
то синхронизация вообще не нужна. Какая разница если выведется на экран половина прошлого кадра и половина нового изредка?
The trick писал(а):Просто создавай буфер под картинку и в отдельном потоке пиши в него, а в другом читай - и все!
The trick писал(а): Я глянул твой пример - там у тебя при вызове MainForm.НовыйКадр в ThreadForm_LoopAction, один поток засыпает и переключается на основной поток - тем самым программа превращается в этом месте в однопоточную. К примеру если основной поток в этот момент будет занят - все потоки будут ждать.
Если у тебя могут быть вызовы из произвольных потоков - то нужно делать маршалинг.
'1) Получаем кадр с OCX "Cam" в чёрти-каком формате указателя:
Dim Buf As Long, Size As Long
Buf = Cam.SnapOne(1&)
Size = Cam.GetImgLen(1&): If Size = 0 Then Exit Function
'2) ВЫВОДИМ ЭТОТ КАДР В ОПЕРАТИВКУ:
Dim hData As Long, pData As Long
hData = GlobalAlloc(2&, Size)
pData = GlobalLock(hData)
CopyMemory Destination:=ByVal pData, Source:=ByVal Buf, Size:=Size
GlobalUnlock hData
'Теперь hData содержит опять же указатель на сырой кадр камеры.
'(Без GlobalLock тоже работает, но говорят, так безопасней.)
'3) ВЫВОДИМ ЕГО В СТРИМ:
Dim Stream As IUnknown
Dim tSI As GdiplusStartupInput
Dim GDIP As Long
Dim Bmp As Long
Dim lData As BitmapData
tSI.GdiplusVersion = 1
If GdiplusStartup(GDIP, tSI) = 0 Then 'если удалось запустить GDI+,
CreateStreamOnHGlobal hData, 1&, Stream 'создаём стрим
'4) ВЫЦЕПЛЯЕМ ИЗ СТРИМА изображение в формат BMP:
Dim R As RECTL
Dim x As Long, y As Long
Dim cBuf() As Long 'массив, в который положим физический КАДР наконец-то!
If GdipLoadImageFromStream(Stream, Bmp) = 0 Then 'Если удалось,
'Смотрим размеры:
GdipGetImageWidth Bmp, x
GdipGetImageHeight Bmp, y
R.Left = 0: R.Right = x
R.Top = 0: R.Bottom = y
If GdipBitmapLockBits(Bmp, R, ImageLockModeRead, PixelFormat32bppARGB, lData) = 0 Then
ReDim cBuf(x * y - 1) 'готовим массив для изображения кадра
lData.Width = lData.Width - 20
CopyMemory Destination:=cBuf(0), Source:=ByVal lData.Scan0, Size:=x * y * 4
'Наконец-то получили изображение в массив cBuf() !
GdipBitmapUnlockBits Bmp, lData
End If
GdipDisposeImage Bmp
End If
Set Stream = Nothing
GdiplusShutdown GDIP
End If
С.Т. писал(а):Но гораздо большая проблема в том, что сам факт запуска modMultiThreading.Initialize и запуска BASS_Init вместе приводит к очень плохим результатам
С.Т. писал(а):Cam.SnapOne(1&)
The trick писал(а):С.Т. писал(а):Cam.SnapOne(1&)
Что такое 1? Где этот OCX? Уверен что формат можно задать при выводе без всякого сжатия и напрямую передавать его в SetDiBitsToDevice.
Сейчас этот форум просматривают: нет зарегистрированных пользователей и гости: 1