GetPixel_() from a video playing on Windows Computer?

Just starting out? Need help? Post your questions and find answers here.
User avatar
matalog
Enthusiast
Enthusiast
Posts: 305
Joined: Tue Sep 05, 2017 10:07 am

GetPixel_() from a video playing on Windows Computer?

Post 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?
User avatar
idle
Always Here
Always Here
Posts: 6026
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

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

Post 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 
User avatar
matalog
Enthusiast
Enthusiast
Posts: 305
Joined: Tue Sep 05, 2017 10:07 am

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

Post 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?
User avatar
idle
Always Here
Always Here
Posts: 6026
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

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

Post 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
User avatar
matalog
Enthusiast
Enthusiast
Posts: 305
Joined: Tue Sep 05, 2017 10:07 am

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

Post 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.
User avatar
idle
Always Here
Always Here
Posts: 6026
Joined: Fri Sep 21, 2007 5:52 am
Location: New Zealand

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

Post by idle »

You should be able to get it as fast as the refresh rate.
Post Reply