VMs thumbnail image via the Virtual Server COM object


So the first week of App Building has gone well.  I’ll write more about my app as soon as it is finished, but I figured I would share a code snippet which you may find helpful.


The Virtual Server 2005 COM API allows you to do a great many things, even get a thumbnail image of the virtual machine’s screen.  Unfortunately however that property is returned as an array of integers which are persisted as Object[].  In other words the functionality is there but you need to convert it to something useful yourself.


The following routine does this convertion for you in VB.NET:


”’ <summary>
”’ Returns the thumbnail for the underlying
”’ Virtual Machine.
”’ </summary>
”’ <remarks>
”’ If the Virtual Machine is off then the thumbnail will
”’ be solid gray. 
”’ Also, this code snippet will only work with
”’ Visual Studio 2005 codenamed Whidbey since it takes
”’ advantage a new VB.NET feature, unsigned integers.

”’ </remarks>
Public ReadOnly Property Thumbnail() As Bitmap
   Get
      
‘ Get the int array from VServer
      Dim pixelArrayObj As Object
()
      pixelArrayObj = CType( _
               
m_comVirtualMachine.Display.Thumbnail, _
               Object
())

      ‘ Convert it to a bitmap
      
Dim bmp As New
Bitmap(64, 48)

      ‘ Pixel index

      Dim i As Integer = 0

      ‘ The thumbnail is always 64×48
      For y As Integer = 0 To 47
         For x As Integer = 0 To
63

            Dim uiPixel As
UInteger = CUInt(pixelArrayObj(i))
            Dim red, green, blue As Integer
            
            
red = CInt((uiPixel >> 8) Mod
256)
            green = CInt((uiPixel >> 16) Mod
256)
            blue = CInt((uiPixel >> 24) Mod
256)

            bmp.SetPixel(x, y, _
                        
Color.FromArgb(red, green, blue))
            i += 1
         Next
      Next

      R
eturn
bmp
   End
Get

End
Property


Disclaimer: The code snippet is offered ‘as is’ and offers no warranties, expressed or implied.  If that 40-line function is somehow responsible for your computer becoming self-aware and taking over the human race, sorry, but don’t blame me or Microsoft.

Comments (4)

  1. In the past I have posted about using Virtual Servers ‘thumbnail’ API to perform virtual machine automation…

  2. Pilosité says:

    Really nice peace of code, usefull !

    Can you explain me briefly what these ‘unsigned’ integer are? I would like to grab why it’s important in this case.

    thanks again for this.

  3. ChrSmith says:

    Pilosité,

    When an integer value is stored in memory it typically takes up 32-bits of information. So in 32-bits there are only 2^32 different combinations of values with no extra room for a ‘negative’ sign.

    A ‘signed’ integer then uses the first bit to store the sign of the value at the loss of precision. So a signed integer is +/- 2^31.

    An ‘unsigned’ integer on the other hand only stores positive values. So it has the full range of 0 – 2^32 but cannot be used to store negative numbers.

    For more information on this please refer to:

    http://en.wikipedia.org/wiki/Two‘s_complement

    The code example required signed integers because of what the data contained. Each value was four colors bound together in a 32-bit data structure (int). In the code I needed to do a little bit shifting to extract the Red, Blue, and Green components.

    If I had casted it to a plain old integer then the bit shifting and modulous operators wouldn’t have worked out…

    Sorry it is so vague, but I hope that answers your question,

    -Chris

  4. TethiS says:

    well I made it work on older vb.net distribution (2003), by replacing

    Dim uiPixel As UInteger = CUInt(pixelArrayObj(i))

    with

    Dim uiPixel As Double = Convert.ToDouble(pixelArrayObj(i))

    here’s the code returning the bitmap:

    Private Function Thumbnail1(ByVal m_comVirtualMachine As VMVirtualMachine) As Bitmap

    Dim pixelArrayObj As Object()

    pixelArrayObj = CType(m_comVirtualMachine.Display.Thumbnail, Object())

    ‘ Convert it to a bitmap

    Dim bmp As New Bitmap(64, 48)

    ‘ Pixel index

    Dim i As Integer = 0

    ‘ The thumbnail is always 64×48

    For y As Integer = 0 To 47

    For x As Integer = 0 To 63

    Dim uiPixel As Double = Convert.ToDouble(pixelArrayObj(i))

    Dim red, green, blue As Integer

    red = CInt((uiPixel >> 8) Mod 256)

    green = CInt((uiPixel >> 16) Mod 256)

    blue = CInt((uiPixel >> 24) Mod 256)

    bmp.SetPixel(x, y, Color.FromArgb(red, green, blue))

    i += 1

    Next

    Next

    Return bmp

    End Function