Toon posts:

[VB] Framebuffer en Pointers

Pagina: 1
Acties:

Verwijderd

Topicstarter
Ik wil iets doen waarvan ik zeker ben dat het kan, alleenkrijg ik het niet voor elkaar. De situatie is als volgt:

Ik gebruik deze call om een frame van een videodevice (webcam in mijn geval) te grabben : SendMessage(lwnd, WM_CAP_GRAB_FRAME_NOSTOP, 0, 0) Deze call stopt 1 frame in de framebuffer (volgens DIT artikel op MSDN)

Voor ieder gecapt frame wordt WM_CAP_SET_CALLBACK_FRAME geroepen (MSDN). Ook dit zit in mijn code verwerkt; ik kan code uitvoeren voor iedere callback.

Nu wil ik de inhoud van de framebuffer opslaan als JPG. VB kan dat zelf niet, maar daar hebben we de dll van Intel ijl11.dll voor.

En nu komt het moment waar ik het niet meer snap: die ijl11.jpg wil een pointer hebben van de DIB die in het memory staat. HOE KOM IK AAN DIE POINTER???

Ik ga er inderdaad vanuit dat die eerste call het frame als DIB in memory wegzet, maar dit weet ik niet zeker. Als dat niet zo is, dan moet er van die zogenaamde framebuffer eerst een DIB gemaakt worden, en dan kom ik weer bij hetzelfde probleem; wat is de pointer van die frame in de framebuffer???

Nb: de code (vb project) om frames van een webcam te grabben is HIER te downen.


Alvast bedankt!!!

  • whoami
  • Registratie: December 2000
  • Laatst online: 23:40
Pointers in VB? Kan dat?

https://fgheysels.github.io/


Verwijderd

Topicstarter
Ja, volgens mij wordt daar gebruik van gemaakt. Zie de onderstaande code,
code:
1
2
3
4
5
6
7
8
9
10
11
12
Dim m_tBI As BITMAPINFOHEADER

m_tBI.biSize = 40
m_tBI.biWidth = camwidth
m_tBI.biHeight = camheight
m_tBI.biPlanes = 1
m_tBI.biBitCount = 24
m_tBI.biCompression = 0
m_tBI.biSizeImage = ((camwidth * 3 + 3) And &HFFFFFFFC) * camheight
m_hDC = CreateCompatibleDC(0)
m_hDIb = CreateDIBSection(m_hDC, m_tBI, 0, m_lPtr, 0, 0)
m_hBmpOld = SelectObject(m_hDC, m_hDIb)


m_lPtr is volgens mij een pointer... of vergis ik mij? Ben geen expert op dit gebied.

Verwijderd

al es wat geprobeerd met varptr en objptr?

Verwijderd

Overigens bevat het volgende topic veel nuttige links voor het programmeren in VB voor een webcam: Programmeren voor webcam

Enjoy :)

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
Hmm - als je de Callback van VFW gebruikt (onFrameCallback) geeft ie geen DIB door maar een VIDEOHDR struct. daarin staat een LPBYTE lpData; maw een Array naar bytes. Je moet mbh verscheidene functies ofvragen welke format deze in feite is - maar de data is pure pixel data. Dus als je zeker weet dat je Webcam 320x240x24bit is kun je die pointer gebruiken om een bitmapstruct in te vullen en door te geven. Voor een projectje een paar jaar geleden heb ik een WapCam geschreven die simpel weg steeds de frame wegschreef dan Imagemajick erop los staat en FTP-ed naar een WapEnabled serverke... Voor realtime stuff kun je eigenlijk niet CAP_NO_STOP gebruiken omdat ie alleen wordt aangeroepen als de PREVIEW is - voor echte capturing moet je de VIDEOSTREAM callback gebruiken die is het meest RealTime...

en je kunt in VB zowat alles met pointers doen als in C/++ ;) proper is het wel niet ;). Dus als het niet aan 25FPS moet en je bent bereid een extern spul als ImageMajick te gebruiken kun je mijn DLL downloaden (met alles erop en eraan) http://www.onnos.com/oovc.html (je can ook zover ik me herinner naar het ClipBoard copieren en als je hetdaar af haalt is het ineens gedecompressed en normaal in DIB formaat... )

Als't sneller moet raad ik je aan de DirectShow te gebruiken want die is backward compatible en de VFW drivers worden uitgefased...

Verwijderd

Topicstarter
Verwijderd schreef op 28 december 2002 @ 19:39:
Overigens bevat het volgende topic veel nuttige links voor het programmeren in VB voor een webcam: Programmeren voor webcam

Enjoy :)
Deze ken ik idd, en dit topic vewijst naar MSDN waar ik ook mijn gegevens vandaan haal. Alleen staat daar niet het antwoord op mijn vraag helaas. Hier staat namelijk hoe je een frame als BMP opslaat, en dat is me wel gelukt alleen moet ik dan die bmp weer converteren naar jpg = extra werk. Maar thanx voor de link anyway! :)

hobbit_be: jij hebt er duidelijk meer kaas van gegeten dan ik! ;)
Ik kan inderdaad wel een frame naar het clipboard plakken, en deze weer als file opslaan, alleen dat vondt ik niet zo'n nette oplossing want als je al iets in je clipboard had staan dan is dat dus ook weg. :( Ik ga nu jouw dll eens proberen, ben zeer benieuwd!!

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
nou als je image in het clipboard staat hoef je die niet op te slaan - je kunt daar de DIb gewoon van pakken.

en wat je ook kun doen is het opslaan van je file naar een RAM drive ;)... (via WriteFile naar een memory block is dat niet te moeilijk)...

ivm DLL tzou kunnen dat je nagscreen krijgt mocht je hem houden stuur ik je wel een zonder op ;)... als je nou wat meer van C++ kende stuurde ik je mijn RealTime C++ classes op.

[edit--

voor clipboard stuff -

http://msdn.microsoft.com...oard/clipboardformats.asp

echt niet moeilijk!!!

[ Voor 20% gewijzigd door hobbit_be op 28-12-2002 21:24 ]


  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 15-08 11:47

Sponge

Serious Game Developer


Verwijderd

Topicstarter
Ik ga het proberen met die ramdrive. Lijkt me zowieso wel interesting daar eens mee te stoeien met VB. Vooral hobbit_be bedankt voor alle info!!!! _/-\o_

Grappig trouwens dat de link die meneer mac-address hierboven geeft wel bekend was bij mij, maar nu zag ik iets wat ik tot dusver over het hoofd gezien had (in de letterbrij) en dat kan ook wel eens de oplossing zijn.

Ik zat even helemaal vast, maar door door jullie hulp kan ik weer even vooruit! Bedankt bedankt bedankt!

  • hobbit_be
  • Registratie: November 2002
  • Laatst online: 04-07-2025
mocht je probs hebben kun je altijd mailen naar hobbit_be@yahoo.com... ben blij dat je er iets aan hebt...

Verwijderd

Topicstarter
OK, thanx hobbit_be!

  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Well, een enorme kick omhoog maar het leek me handig om hier maar verder te gaan omdat ik anders bovenstaande links weer allemaal voorbij zie komen straks :P

Ik heb dus ongeveer hetzelfde probleem, alleen wil ik de inhoud van de array niet als image opslaan maar in een Image plaatsen. En dat realtime, dus even opslaan en dan laden is er niet bij.
Misschien dat een RAM drive wat is (klinkt handig) maar ik zou niet weten hoe :) Google kan me niet echt daarmee helpen. Maar eigenlijk verwachtte ik gewoon een functie dat je je data in de image.picture kan storten.
En nu we het toch over images hebben, wat is de container? Of sla ik hiermee de spijker op de kop en kan ik via een container data erin stoppen? Zou wel mooi zijn :)

Owhjah, tis vb6 en niet vb.net.

[edit] *lama*

[ Voor 24% gewijzigd door wacco op 11-07-2003 20:25 ]

Spolap: Interactive webcomic


  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 15-08 11:47

Sponge

Serious Game Developer

Hmm.. heb je de oplossing, of niet? :) Die edit maakt het een beetje onduidelijk. :)

Overigens kun je SetBitmapBits of SetDibbits gebruiken (Als je een array met pixels bedoeld) voor een voorbeeld kan je bijvoorbeeld op www.vbapi.net kijken, of bijvoorbeeld op mijn site (hieronder) met een simpele raytracer (versie 1), die setbitmapbits gebruikt volgens mij.

  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Ehh, nee ik had het nog niet werkend :) Maar ik had er wat bijgeplakt en dat was een beetje zinloos, vandaar.
Die vbapi.net site doet het niet, maar ik ga wel even m'n MSDN induiken voor die SetBitmapBits functie. Het is volgens mij namelijk gewoon een array met pixels (al weet ik niet precies hoe het met de r/g/b zit enzow) dus misschien dat het wat is.

-edit-
Ik heb nou een paar van die bitmap functies lopen uitproberen, maar krijg het niet aan de praat. Waarschijnlijk ook door m'n onkunde met handles en longs en wat Image1.picture verwacht. :) Ik gooi het allemaal door elkaar en weet niet hoe ik de ene in de andere kan veranderen. De volgende regel;

Form1.Image1.Picture = CreateCompatibleBitmap(VideoHeader.lpData, 176, 144)

werkt dus niet, maar dat komt misschien ook omdat de functie een handle teruggeeft, picture een stdpicture verwacht, videoheader.lpdata een handle moet zijn en een long is, en hij kent de hele functie ook niet. Die zou ik moeten declareren maar weet niet welke dll het is :/
CreateCompatibleBitmap werd ik naar verwezen via CreateBitmap (die voor monochroom bleek te zijn, compatible was sneller). Daar was ik terecht gekomen omdat Setbitmapbits eigenlijk alleen maar voor compabiliteit bedoelt was met windows - 16 bits. Ze raadden me SetDIbits aan, maar die is complete overkill voor mij, ik snap er geen *** van (ik heb helemaal geen bitmapinfo en die typedef is vaag? en zo zijn er nog wel een paar rare dingetjes)
Ook omdat het allemaal met bitmaps te maken heeft vraag ik me een beetje af of ik niet in plaats van een image object iets anders moet gebruiken. Een bitmap ofzo... (dahh) maar dan weet ik weer niet hoe ik die in m'n form moet invoegen. Is die als component ergens beschikbaar?
Anyway, die array wordt dus gevuld met data van de driver en ik denk dat het gewoon R-G-B-volgende kleur is, maar ik weet het niet zeker. Ik ga even wat rekenen om te kijken of dat uit zou komen met de grootte van de data in totaal.

-edit2-
heb wat zitten rekenen en ik heb per pixel exact 3 bytes, dus dat zou dan idd een byte R, een byte G en een byt B zijn. :) (dwBytes = 76032, 176x144 = 25334, die twee gedeeld geeft 3)

[ Voor 76% gewijzigd door wacco op 12-07-2003 00:20 ]

Spolap: Interactive webcomic


  • Sponge
  • Registratie: Januari 2002
  • Laatst online: 15-08 11:47

Sponge

Serious Game Developer

Je zou nu iig met SetPixel (ook API) een test kunnen maken om te zien of wat er in de array staat echt klopt. SetPixel gebruikt als color een longm, dus je moet RGB(jeR,jeG,jeB) gebruiken om je kleur te krijgen. :)

SetBitmapBits is gedeeltelijk overkill :). Maar die type is er niet voor niets. Ik zal een stukje uit m'n raytracer code plakken (die dus op m'n site hieronder staat)

code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
    '//Set bitmap ino and create our pixel array
    With BInfo.bmiHeader
       .biSize = 40
       .biWidth = frmMain.picRay.ScaleWidth
       .biHeight = frmMain.picRay.ScaleHeight
       .biPlanes = 1
       .biBitCount = 32
       .biCompression = 0
       .biClrUsed = 0
       .biClrImportant = 0
       .biSizeImage = frmMain.picRay.ScaleWidth * frmMain.picRay.ScaleHeight
    End With
    
    '//Redim our array to the size of the picturebox
    With frmMain.picRay
        ReDim Bits(0 To BInfo.bmiHeader.biWidth - 1, 0 To BInfo.bmiHeader.biHeight)
    End With


Het enige wat je hier dus zou moeten veranderen is de afmeting van je picturebox (wel op scaletype = vbpixel zetten onder properties, en de border uitzetten.)

die bits array kan je eigen array zijn met kleuren die van mij ziet er zo uit

code:
1
2
3
4
5
Private Type ColorFloat
    R As Byte
    G As Byte
    B As Byte
End Type


Ik denk dat je array met pixels ongeveer hetzelfde eruit ziet :)

Overigens gebruikte ik in m'n code multi-dim array, zodat ik makkelijk x & y heb:
code:
1
2
3
4
5
                With Bits(X, Y)
                    .rgbRed = 0
                    .rgbBlue = 0
                    .rgbGreen = 0
                End With


Dit zou dus pixel op positie x,y zwart maken

En uiteindelijk "sturen" we alle pixels naar de picturebox :D

code:
1
2
3
4
5
6
7
8
    With frmMain.picRay
        '//Set the bits back to the picture
        SetDIBits lngHDC, lngImageHandle, 0, BInfo.bmiHeader.biHeight
(0, 0), BInfo, DIB_RGB_COLORS
        
        '//Refresh
        .Refresh
    End With


Overigens komen de image handles hiervandaan

code:
1
2
3
4
5
    '//Device Context
    lngHDC = frmMain.picRay.hdc

    '//Image handle
    lngImageHandle = frmMain.picRay.Image.Handle


Ik hoop dat het nu iets duidelijker is. :) Zo niet, probeer eens met die code te "klooien" dat werkt vaak het beste (is mijn ervaring :P) ;)

Overigens een waarschuwing, voor ik het vergeet. Volgens mij moet je desktop "kleur diepte" boven de 16 bit zijn. (voor setdibits en setbitmapbits)

[ Voor 3% gewijzigd door Sponge op 12-07-2003 10:39 . Reden: Ik dacht dat code tags wrappen?? ]


  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

Ik heb nu;
code:
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
    '//Set bitmap ino and create our pixel array
    With Binfo.bmiHeader
       .biSize = 40
       .biWidth = 176
       .biHeight = 144
       .biPlanes = 1
       .biBitCount = 32
       .biCompression = 0
       .biClrUsed = 0
       .biClrImportant = 0
       .biSizeImage = 176 * 144
    End With
    
    '//Redim our array to the size of the picturebox
    '//moet deze array Bits persé in een with Form1.Picture1?
    With Form1.Picture1
        ReDim Bits(0 To Binfo.bmiHeader.biWidth - 1, _
            0 To Binfo.bmiHeader.biHeight)
    End With

    RtlMoveMemory VarPtr(Bits(0, 0)), VideoHeader.lpData, _ 
        VideoHeader.dwBytesUsed
    
    With Form1.Picture1
        SetDIBits Form1.Picture1.hDC, Form1.Picture1.Image.Handle, _
            0, Bits(0, 0), Binfo, DIB_RGB_COLORS
    End With

Maar hij kent de functie SetDIBits niet. Nogal logisch want ik heb em niet gedeclareerd, in welke dll zit hij? Verder weet ik niet of deze code nou goed is maar volgens mij wel. :P
Wat ik me afvroeg (zie ook het extra commentaar), moet die array persé in een With Form1.Picture1 staan? Of kan hij er ook gewoon buiten? En moet het een x,y array zijn? Anders kan het volgens mij veel sneller door gewoon meteen in de SetDIBits ipv Bits(0,0) aan te roepen VideoHeader.lpData te gebruiken (of, zoals hij eerder in de code (zie je hier niet) wordt gekopieerd; VideoData(0) ). Al weet ik dan weer niet of hij em wel kan vinden omdat de SetDIBits weer in een with staat. Om eerlijk te zijn; ik ben helemaal niet bekend met 'With' dus weet ook niet wat wel en wat niet kan. :)

-- Owh en is het geen probleem dat ik niks declareer als types maar gewoon met with's aan het klussen sla? Hij gaf er niet meteen een error op maar erg netjes is het volgens mij niet.

[ Voor 7% gewijzigd door wacco op 12-07-2003 16:28 ]

Spolap: Interactive webcomic


  • wacco
  • Registratie: Augustus 2002
  • Laatst online: 21-03-2023

wacco

cli, hlt.

*kick*

Ik heb het nog steeds niet voor elkaar :( Ook vind ik het een beetje vage type, moet ik naast Binfo.Bmiheader nog meer dingen plaatsen? Of is het alleen maar Binfo.BmiHeader.de_rest? Als dat niet zo is kan het weer wat korter natuurlijk. Verder bedacht ik me dat ik types toch ook gewoon meteen standaard waardes mee kan geven? Ik gebruik em toch maar één keer in het hele programma...

Spolap: Interactive webcomic


  • curry684
  • Registratie: Juni 2000
  • Laatst online: 13-08 16:46

curry684

left part of the evil twins

MSDN Library Online, zoek daar eens op SetDIBits. Het is niet de bedoeling dat wij hier je code gaan schrijven, maar dat je zelf met de gegeven hints ook wat onderzoek doet en uitprobeert.

Professionele website nodig?


Verwijderd

als je voor een parameter ByRef zet, geeft hij dan geen pointer door :?
Pagina: 1