Page 1 of 1

GetPixel_() from a video playing on Windows Computer?

Posted: Tue Aug 27, 2024 10:28 pm
by matalog
How can I use GetPixel_() to read from a video playing on Windows 10?

I got some help before about using GetPixel_(), but it seems to be constrained to certain windows. The code was:

Code: Select all

Define hwnd, hdc, pt.Point,p1.Point, rc.RECT, x, y
Define wid = 3, hig = 3,size = 50
Dim color(wid,hig)

OpenWindow(0,0,0,wid*size,hig*size,"", #PB_Window_Tool|#PB_Window_SystemMenu)
CanvasGadget(0,5,5,WindowWidth(0)-10,WindowHeight(0)-10)
StickyWindow(0, 1)

Repeat
	Define time = ElapsedMilliseconds()
	If pt\x <> DesktopMouseX() Or pt\y <> DesktopMouseY()
		pt\x = DesktopMouseX()
		pt\y = DesktopMouseY()
		
		hwnd = WindowFromPoint_(PeekQ(pt))
		If hwnd
			hdc = GetDC_(hwnd)
			If hdc
				For y = 0 To hig-1
					For x = 0 To wid-1
						p1\x = pt\x + x - wid/2
						p1\y = pt\y + y - hig/2
						If ScreenToClient_(hwnd , p1)
							color(x, y) = GetPixel_(hdc, p1\x, p1\y)
						EndIf
					Next
				Next
				ReleaseDC_(hwnd, hdc)
			EndIf
		EndIf	
		
		SetWindowTitle(0, Str(ElapsedMilliseconds() - time) + " ms")
		StartDrawing(CanvasOutput(0))
		For y = 0 To hig-1
			For x = 0 To wid-1
				Box(OutputWidth()/wid*x,OutputHeight()/hig*y,OutputWidth()/wid,OutputHeight()/hig,color(x,y))
			Next
		Next
		StopDrawing()
	EndIf
	
	While WindowEvent():If Event()=#PB_Event_CloseWindow:End:EndIf:Wend
ForEver
And as I said, it works fine on the window visible upon program launch, how can I amend it to read pixel data from a video playing in a browser for example?

Re: GetPixel_() from a video playing on Windows Computer?

Posted: Tue Aug 27, 2024 11:25 pm
by idle
You will need to use bitblt with #CAPTUREBLT and the window has to be visible
something like this

Code: Select all

Procedure Screenshot(hImage,x,y,width,Height)   
   
   Protected thdc,hdc 
   
   hdc = GetDC_(0)  
   #CAPTUREBLT = $40000000 
   If hImage = 0
     hImage = CreateImage(#PB_Any,Width,Height,32) 
   EndIf 
   
   If hImage
     desthdc = StartDrawing(ImageOutput(hImage))
     BitBlt_(desthdc,0,0,Width,Height,srcdc,x,y,#SRCCOPY | #CAPTUREBLT)
     StopDrawing() 
     DeleteDC_(hdc)
   EndIf 
     
   ProcedureReturn hImage
   
 EndProcedure 

Re: GetPixel_() from a video playing on Windows Computer?

Posted: Wed Aug 28, 2024 12:11 am
by matalog
idle wrote: Tue Aug 27, 2024 11:25 pm You will need to use bitblt with #CAPTUREBLT and the window has to be visible
something like this

Code: Select all

Procedure Screenshot(hImage,x,y,width,Height)   
   
   Protected thdc,hdc 
   
   hdc = GetDC_(0)  
   #CAPTUREBLT = $40000000 
   If hImage = 0
     hImage = CreateImage(#PB_Any,Width,Height,32) 
   EndIf 
   
   If hImage
     desthdc = StartDrawing(ImageOutput(hImage))
     BitBlt_(desthdc,0,0,Width,Height,srcdc,x,y,#SRCCOPY | #CAPTUREBLT)
     StopDrawing() 
     DeleteDC_(hdc)
   EndIf 
     
   ProcedureReturn hImage
   
 EndProcedure 
Thanks for replying, I'm knee deep in an exciting project, and not fully adept in PureBasic and especially not IDE calls.

Does that Procedure allow access to any windows that are visible?

I will only have to access a few pixels of the visible windows, and one window at a time. I'm not exactly sure how to use this procedure to read only a pixel at x=200,y=200 of the visible screen, for example. Could you possibly help me work that out?

Re: GetPixel_() from a video playing on Windows Computer?

Posted: Wed Aug 28, 2024 2:56 am
by idle
try this should work

Code: Select all

Procedure Screenshot(hdc,hImage,x,y,width,Height)   
   
   Protected thdc 
    
   #CAPTUREBLT = $40000000 
   If hImage = 0
     hImage = CreateImage(#PB_Any,Width,Height,32) 
   EndIf 
   
   If hImage
     desthdc = StartDrawing(ImageOutput(hImage))
     BitBlt_(desthdc,0,0,Width,Height,hdc,x,y,#SRCCOPY | #CAPTUREBLT)
     StopDrawing() 
     DeleteDC_(hdc)
   EndIf 
     
   ProcedureReturn hImage
   
 EndProcedure 

Define hwnd, hdc, pt.Point,p1.Point, rc.RECT, x, y,himage
Define wid = 3, hig = 3,size = 50
Dim color(wid,hig)

OpenWindow(0,0,0,wid*size,hig*size,"", #PB_Window_Tool|#PB_Window_SystemMenu)
CanvasGadget(0,5,5,WindowWidth(0)-10,WindowHeight(0)-10)
StickyWindow(0, 1)

Repeat
	Define time = ElapsedMilliseconds()
	If pt\x <> DesktopMouseX() Or pt\y <> DesktopMouseY()
		pt\x = DesktopMouseX()
		pt\y = DesktopMouseY()
		
		hwnd = WindowFromPoint_(PeekQ(pt))
		If hwnd
			hdc = GetDC_(0);hwnd)
			himage = Screenshot(hdc,himage,pt\x,pt\y,10,10)
		EndIf	
		
		SetWindowTitle(0, Str(ElapsedMilliseconds() - time) + " ms")
		StartDrawing(CanvasOutput(0))
		DrawImage(ImageID(himage),x,y)
		StopDrawing()
	EndIf
	
	While WindowEvent():If Event()=#PB_Event_CloseWindow:End:EndIf:Wend
ForEver

Re: GetPixel_() from a video playing on Windows Computer?

Posted: Wed Aug 28, 2024 2:15 pm
by matalog
idle wrote: Wed Aug 28, 2024 2:56 am try this should work
Thanks, that does work, it is really amazing actually, that it can get the screen data so fast.

Out of interest, as it might be a benefit to me, is it possible to get just a few pixels of information any faster than that?

Thanks again.

Re: GetPixel_() from a video playing on Windows Computer?

Posted: Wed Aug 28, 2024 9:09 pm
by idle
You should be able to get it as fast as the refresh rate.