Want to protect your cyber security and still get fast solutions? Ask a secure question today.Go Premium


Screen Capture through Winsock

Posted on 2003-02-26
Medium Priority
Last Modified: 2013-11-26
I know there are many / many examples out there of different ways to grab screen captures through API, keyboard commands, etc...  

However, I am creating an application for remote assistance that will need to work slightly differently, in that it will be the server controlling the client and receiving screen captures of the client.  I currently have a version that is capturing the screen as a BMP to a file and then reading that file and killing it, sending the data to the other computer, which stores it as a file, reads it and then kills and displays it.

My problems are, that this seems to be more work than is necessary.  Are there any quick ways to create a smaller footprint to transfer without having to write it to file on one or both ends?  I would rather send them as JPG's since, the BMP file is coming in at over 4MB!

Also, is there a way to capture the data and send directly through winsock and then put it directly into the picture/image box control without having to save the file and call loadimage?

Thanks in Advance on this one!
I'll add more points for a really helpfull answer!

Question by:HHSB
LVL 16

Expert Comment

ID: 8029089
Interesting...but poor points amount :)

Author Comment

ID: 8029197
Like I said above...

I'll add more points for a really helpfull answer!

LVL 28

Assisted Solution

vinnyd79 earned 148 total points
ID: 8029787
You could zip the bmp files as they should compress quite a bit.I remember doing something like that a while back.What I would recommend is installing the free version of tridiavnc on the machines as a service.It comes with a reg script you can run to disable the system tray icon.Then you can shell the viewer from your vb program.The viewer supports a /viewonly switch so you can view the other screen in real time.If you launch it without the /viewonly switch then you will be able to take control of the desktop similar to pcANYWHERE.

Industry Leaders: We Want Your Opinion!

We value your feedback.

Take our survey and automatically be enter to win anyone of the following:
Yeti Cooler, Amazon eGift Card, and Movie eGift Card!


Expert Comment

ID: 8032303
as a partial solution, use glabcore component

it will enable you to grab the desktop picture and save it as a jpg which will reduce the traffic

Author Comment

ID: 8034935

     I took a look at the glabcore component, and it looks great.  The question I had is, would it be possible to use that library to send the compressed data through winsock and then recompress it on the other end without having to create files on either end?  

How would I accomplish this if it is possible?



Author Comment

ID: 8037214
Here is what I am doing now:

On the Send Side of Things:
(gPic1 is a screen capture)

    Dim gPic1 As New GlabPicture
    Dim gSend As New GlabBuffer
    Dim gJpg As New GlabJPEG


    gJpg.Grayscale = False
    gJpg.ForceBaseline = True
    gJpg.OptimizeCoding = True
    gJpg.Upsample = True
    gJpg.DCT = glabjpegFastDCT
    gJpg.Quality = 10
    gJpg.DecompressorSmoothing = True
    gJpg.CompressorSmoothing = 0
    Set gSend = gJpg.Compress(gPic1)


   winsock.senddata "[START]" & gSend.binarystring & _

On the Receive side of things:

    If InStr(strData, "[START]") Then
        Set buffer = Nothing
        buffer.BinaryString = Replace( _  
                  strData, "[START]", "")
        process = True
    End If
    If InStr(strData, "[STOP]") Then
        If process = True Then
            'Small Image was Sent
            buffer.BinaryString = _
                  Replace(buffer.BinaryString, _
                  "[STOP]", "")
            buffer.BinaryString = buffer.BinaryString & _
                Replace(strData, "[STOP]", "")
            process = True
        End If
        Set gJPG = Nothing
        set gPic1 = gJPG.Decompress(buffer)
        gPic1.ScaleTo _
            ScaleX(Picture1.Width, vbTwips, vbPixels), _
            ScaleX(Picture1.Height, vbTwips, vbPixels)
        Picture1.Picture = gPic1.Picture
        End If
    If process = False Then
        buffer.BinaryString = buffer.BinaryString & strData
    End If


    The data seems to make it okay, as long as the picture is small enough that the entire image gets sent (more on this below).  When I print out the binarystring that is sent, it matches the one that arrives, however, when I decompress it I get an error.  

    Also, when the image is large, the binarystring seems to get chopped short when it is being sent, is there a simple way to chop the data into smaller chunks?

Thanks in advance everyone for your help.  I will give 450 points for a correct answer that helps me get this working.


Accepted Solution

DanAvni earned 152 total points
ID: 8039914
I think that what you should do is this:
take the ByteArray from the glab buffer. build a string that contains the hex representation of each byte, send that over (this will make sure that the data sent is only the letters 0-9,A-F:
untested code:
dim sBuff as string,Ix as long,Buff() as byte
for ix=lbound(buff) to ubound(buff)
   sbuff=sbuff & hex(buff(ix))
next ix
sbuff="[START]" & sbuff & "[END]"

on the recieveing side, then recieving the data concat it into a string variable and not the glab buffer. at the end of it string the "[START]","[END]" delimiters and decode the buffer back into a byte array and set that byte array to the glab buffer:
again untested code
redim buff(len(sbuff)/2) as byte
dim sTmp as string,Ix as long
while len(sBuff)>0
   buff(ix)=val("&h" & stmp)
then give this buff to the glab buffer.

note that on this side the redim might not work and might contain an extra cell (debug it to make sure it's ok)

Author Comment

ID: 8043488
I have updated my code to include the suggestions above.  I'm not sure what you meant by contain an extra cell, but this may be happening.  When I debug the program I learn that the redim statement breaks down to an odd number for the len(sbuff), which makes 1/2 of that a fractional number (X.5)

The code then halts on the line:
buff(ix) = val("&h" & stmp)

with the message: Subscript Out of Range.

The conversions and the redmin statement are all new to me, so I'm not exactly sure what to do at this point to fix this error.

Here is the code I have on the send Side:

Dim sBuff As String, Ix As Long, Buff() As Byte
Buff = gSend.ByteArray
For Ix = LBound(Buff) To UBound(Buff)
sBuff = sBuff & Hex(Buff(Ix))
Next Ix
sBuff = "[START]" & sBuff & "[STOP]"
ok = safeSend(sBuff)

Here is the code I have on the Receive Side:

ReDim Buff(Len(buffer2) / 2) As Byte
Dim sTmp As String, Ix As Long
Ix = 0

While Len(buffer2) > 0
     sTmp = Left(buffer2, 2)
     sbuff = Mid(buffer2, 3)
     Buff(Ix) = Val("&h" & sTmp)
     Ix = Ix + 1
Set buffer.ByteArray = Buff
Any more insight that you could provide would be very helpful, and thanks for all your help so far.


Author Comment

ID: 8043812
There was a typo in the section:

While Len(buffer2) > 0
    sTmp = Left(buffer2, 2)
    sbuff = Mid(buffer2, 3)
    Buff(Ix) = Val("&h" & sTmp)
    Ix = Ix + 1

the 3rd line should have read, and now reads, buffer2 = mid(buffer2,3)

This then pushes the error down to later in the code, to the same place it was before the hex conversion...

Set buffer = Nothing
buffer.ByteArray = Buff

'Same Settings as used to compress
'Don't know if this matters
Set gJPG = Nothing
gJPG.Grayscale = False
gJPG.ForceBaseline = True
gJPG.OptimizeCoding = True
gJPG.Upsample = True
gJPG.DCT = glabjpegFastDCT
gJPG.Quality = 100
gJPG.DecompressorSmoothing = True
gJPG.CompressorSmoothing = 10

'This line gives the error:
set gPic1 = gJPG.Decompress(buffer)

The Error is:

Method 'Decompress' of object 'IGlabJPEG' failed


Author Comment

ID: 8044162
The data converts to Hex and transfers byte for byte from the client the the server, however, it does not convert back to the same value when the recieving computer rebuilds the byte array as it existed on the sending computer.


Author Comment

ID: 8044397
Turned out to be the hex conversion code.  Otherwise, it seems to be working now.  I will play around with it over the weekend.  If it all works out I will deposit the points for the question on Monday.  Thanks!

Original: sbuff = sbuff & hex(buff(ix))
Modified: sbuff = sbuff & right("0", + hex(buff(ix)),2)



Expert Comment

ID: 8901059
This old question needs to be finalized -- accept an answer, split points, or get a refund.  For information on your options, please click here-> http:/help/closing.jsp#1 
Experts: Post your closing recommendations!  Who deserves points here?
LVL 49

Expert Comment

ID: 8983474
Moderator, my recommended disposition is:

    Split points between: vinnyd79 and DanAvni

DanRollins -- EE database cleanup volunteer

Featured Post

Free Tool: ZipGrep

ZipGrep is a utility that can list and search zip (.war, .ear, .jar, etc) archives for text patterns, without the need to extract the archive's contents.

One of a set of tools we're offering as a way to say thank you for being a part of the community.

Question has a verified solution.

If you are experiencing a similar issue, please ask a related question

This article will show, step by step, how to integrate R code into a R Sweave document
The purpose of this article is to demonstrate how we can use conditional statements using Python.
The viewer will learn how to clear a vector as well as how to detect empty vectors in C++.
The viewer will be introduced to the member functions push_back and pop_back of the vector class. The video will teach the difference between the two as well as how to use each one along with its functionality.
Suggested Courses

581 members asked questions and received personalized solutions in the past 7 days.

Join the community of 500,000 technology professionals and ask your questions.

Join & Ask a Question