Page 1 of 1

Screen capture issue

Posted: Wed Apr 24, 2024 4:15 pm
by Etayson
Here is a small piece of code that captures the screen. Over time (It’s always different) the capture stops working(BitBlt_ doesn`t capture new image) or breaks with an error => ImageOutput(0) is NULL (0 value)
What is the problem can be?
[Windows 10, Unicode mode, threadSafe, PB 5.31 x64]

Code: Select all

Procedure capturescreen(i)
  Protected srcDC, trgDC, BMPHandle.l, dm.DEVMODE, hDC, resultImg = 0, bitBlt, outputId, ScreenWidth, ScreenHeight, wx, wy, ci.CURSORINFO
  Protected xpos, ypos
  
  
  Repeat
    ScreenWidth = GetSystemMetrics_(#SM_CXSCREEN)
    ScreenHeight = GetSystemMetrics_(#SM_CYSCREEN)
    If wx<>ScreenWidth Or wy<>ScreenHeight
      wx = ScreenWidth      
      wy = ScreenHeight
      
      If IsImage(0)
        FreeImage(0)
      EndIf
      
      If Not CreateImage(0, ScreenWidth, ScreenHeight, 24)        
        Break
      EndIf
    EndIf
    srcDC = GetDC_(#Null);CreateDC_("DISPLAY", "", "", #Null)
    trgDC = CreateCompatibleDC_(srcDC)
    BMPHandle = CreateCompatibleBitmap_(srcDC, ScreenWidth, ScreenHeight)
    SelectObject_( trgDC, BMPHandle)    
    bitBlt = BitBlt_(trgDC, 0, 0, ScreenWidth, ScreenHeight, srcDC, 0, 0, #SRCCOPY)    
    
    hDC = StartDrawing(ImageOutput(0) )     
    DrawImage(BMPHandle, 0, 0)
    ci\cbSize = SizeOf(CURSORINFO)
    GetCursorInfo_(@ci)
    xpos = ci\ptScreenPos\x
    ypos = ci\ptScreenPos\y
    GetIconInfo_(ci\hCursor, iconinfo.ICONINFO)      
    DrawIconEx_(hDC, xpos - iconinfo\xHotspot ,ypos - iconinfo\yHotspot, ci\hCursor, 32, 32, 0, 0, #DI_NORMAL|#DI_COMPAT )    
    StopDrawing() 
    
    CopyImage(0, 5)
    ResizeImage(5, 580 , 580)
    SetGadgetAttribute(0, #PB_Canvas_Image , ImageID(5))
    FreeImage(5)
    
    DeleteObject_(trgDC)
    ReleaseDC_(BMPHandle, srcDC)
    ReleaseDC_(#Null, srcDC)
    DeleteObject_(BMPHandle)         
    Delay(50)
  ForEver
  
  If IsImage(0)
    FreeImage(0)
  EndIf
  
EndProcedure

If OpenWindow(0, 0, 0, 600, 600, "CaptureScreenInUnicodeMode", #PB_Window_SystemMenu | #PB_Window_ScreenCentered |#PB_Window_SizeGadget | #PB_Window_MinimizeGadget | #PB_Window_MaximizeGadget)
  
  CanvasGadget(0,  10, 10, 580, 580)   
  CreateThread(@capturescreen(),0)
  Repeat
    Event = WindowEvent() 
    Delay(10)    
  Until Event = #PB_Event_CloseWindow
  
EndIf

Re: Screen capture issue

Posted: Wed Apr 24, 2024 5:12 pm
by jacdelad
Hi,
I have no problems here (Windows 10 x64, PB 6.11 Beta 1 x64 ASM). What is "over time"? Some seconds, minutes, hours??

A thing to mention:
The whole ScreenWidth/ScreenHeight-thing, do you expect the screen to change resolution? If not, I wouldn't put this inside the loop.

Re: Screen capture issue

Posted: Wed Apr 24, 2024 5:36 pm
by netmaestro
Try with this at the top of your code:

Code: Select all

#CAPTUREBLT = $40000000 
And then apply the flag to your BitBllt command:

Code: Select all

bitBlt = BitBlt_(trgDC, 0, 0, ScreenWidth, ScreenHeight, srcDC, 0, 0, #SRCCOPY|#CAPTUREBLT)
If you don't use the CAPTUREBLT flag layered windows won't get included.

Re: Screen capture issue

Posted: Wed Apr 24, 2024 5:38 pm
by Etayson
jacdelad wrote: Wed Apr 24, 2024 5:12 pm Hi,
I have no problems here (Windows 10 x64, PB 6.11 Beta 1 x64 ASM). What is "over time"? Some seconds, minutes, hours??

A thing to mention:
The whole ScreenWidth/ScreenHeight-thing, do you expect the screen to change resolution? If not, I wouldn't put this inside the loop.
I just took out a piece of code. In fact, there is quite a large program for remote access. And yes, it needs to track changes in the size of the desktop. This particular code breaks for me in different ways, sometimes after 5 minutes, sometimes after a minute..
Now i have error =>the specified #Image is not initialised.
I've been dancing with a tambourine for a week now around screen capture, I've already tried different capture options. Always the same image crashes or the capture is not updated.

Re: Screen capture issue

Posted: Wed Apr 24, 2024 5:40 pm
by Etayson
netmaestro wrote: Wed Apr 24, 2024 5:36 pm Try with this at the top of your code:

Code: Select all

#CAPTUREBLT = $40000000 
And then apply the flag to your BitBllt command:

Code: Select all

bitBlt = BitBlt_(trgDC, 0, 0, ScreenWidth, ScreenHeight, srcDC, 0, 0, #SRCCOPY|#CAPTUREBLT)
If you don't use the CAPTUREBLT flag layered windows won't get included.
I tried this and tried with this

Code: Select all

DeskDC = GetDC_(GetDesktopWindow_())      
      If DeskDC        
        BitBlt_(hDC,0,0,w,h,DeskDC,0,0,#SRCCOPY|#CAPTUREBLT)        
      EndIf        
      ReleaseDC_(GetDesktopWindow_(),DeskDC)
The same issue.

Re: Screen capture issue

Posted: Wed Apr 24, 2024 5:54 pm
by PeDe
Perhaps the error is in 'BMPHandle.l''? Integer would be correct.

Peter

Re: Screen capture issue

Posted: Wed Apr 24, 2024 6:07 pm
by Etayson
PeDe wrote: Wed Apr 24, 2024 5:54 pm Perhaps the error is in 'BMPHandle.l''? Integer would be correct.
Peter
Yeah, it was originally BMPHandle.i then I saw somewhere that use BMPHandle.l. Anyway result is the same.

Re: Screen capture issue

Posted: Wed Apr 24, 2024 6:39 pm
by PeDe
Windows 7 x64
The Task Manager shows me that the number of GDI objects is constantly increasing. I think only 10,000 are allowed, but I'm not sure. With my slow PC it takes a long time to count up, I've only cracked the 3,000 mark.

Edit:
Here there was the first visible error with 9,999 GDI objects. Then the value fluctuated around 10,000 until there was the error with 'The specified #Image is not initialized.

Peter

Re: Screen capture issue

Posted: Wed Apr 24, 2024 6:55 pm
by Etayson
PeDe wrote: Wed Apr 24, 2024 6:39 pm Windows 7 x64
The Task Manager shows me that the number of GDI objects is constantly increasing. I think only 10,000 are allowed, but I'm not sure. With my slow PC it takes a long time to count up, I've only cracked the 3,000 mark.

Edit:
Here there was the first error with 9.999 GDI objects.

Peter
Exactly, you're right GetIconInfo_ is produce GDI objects.. need to be clear i think with DeleteObject_(iconinfo\hbmMask)
DeleteObject_(iconinfo\hbmColor)

Edit: Thanks Peter, you save my brain. Now all works like sharm.

Re: Solved! Screen capture issue

Posted: Fri Apr 26, 2024 2:08 pm
by Etayson
Hi, need advice on how to improve the operation of the screen capture procedure and transmitting it over the Internet.
There is image 0, into which the screen is copied using BitBilt, there is also other buffer in memory where stored previous frame.
The image 0 is divided into rectangles for example, 20*12 pixels. Each rectangle in current frame is compared with the previous frame and if there is a discrepancy, then this rectangle is copied to the accumulation buffer.
Then this accumulation buffer is encoded by a Jpeg plugin and transmitted via the Internet.
But there is a problem with the artifacts. When simply encode the some image using Jpeg, it comes out fine. But if encode a buffer consisting of rectangles from different screen chats, then some ugly artifacts appear.
The goal is to minimize traffic as much as possible, but at the same time ensure that the image is acceptable. Therefore, using plugins like PNG is not an option.
Image
Edit: The artifact appears when not the entire frame is transmitted, but some pieces of the frame. For example, when the cursor moves, only rectangles located in the cursor area are transmitted. And this is where these artifacts appear.