-1

This question may have been asked before but im just starting out with VB.Net and was given this application to fix that uses the webcam of the pc/ tablet but I cant figure out the pinvoke error

here is my code:

Imports System.IO

Public Class frm

CaptureWebCam

    Const CAP As Short = &H400S
    Const CAP_DRIVER_CONNECT As Integer = CAP + 10
    Const CAP_DRIVER_DISCONNECT As Integer = CAP + 11
    Const CAP_EDIT_COPY As Integer = CAP + 30
    Const CAP_SET_PREVIEW As Integer = CAP + 50
    Const CAP_SET_PREVIEWRATE As Integer = CAP + 52
    Const CAP_SET_SCALE As Integer = CAP + 53
    Const WS_CHILD As Integer = &H40000000
    Const WS_VISIBLE As Integer = &H10000000
    Const SWP_NOMOVE As Short = &H2S
    Const SWP_NOSIZE As Short = 1
    Const SWP_NOZORDER As Short = &H4S
    Const HWND_BOTTOM As Short = 1

    Dim iDevice As Integer = 0 ' Normal device ID
    Dim hHwnd As Integer ' Handle value to preview window
    Public image_base64String As String
    ' Declare function from AVI capture DLL.

    Declare Auto Function SendMessage Lib "user32" Alias "SendMessageA" (ByVal hwnd As Integer, ByVal wMsg As Integer, ByVal wParam As Integer, ByVal lParam As Object) As Integer
    Declare Auto Function SetWindowPos Lib "user32" Alias "SetWindowPos" (ByVal hwnd As Integer, ByVal hWndInsertAfter As Integer, ByVal x As Integer, ByVal y As Integer, ByVal cx As Integer, ByVal cy As Integer, ByVal wFlags As Integer) As Integer
    Declare Auto Function DestroyWindow Lib "user32" (ByVal hndw As Integer) As Boolean
    Declare Auto Function capCreateCaptureWindowA Lib "avicap32.dll" (ByVal lpszWindowName As String, ByVal dwStyle As Integer, ByVal x As Integer, ByVal y As Integer, ByVal nWidth As Integer, ByVal nHeight As Short, ByVal hWndParent As Integer, ByVal nID As Integer) As Integer

    Private Sub OpenForm()
        Dim iHeight As Integer = picCapture.Height
        Dim iWidth As Integer = picCapture.Width

        ' Open Preview window in picturebox .
        ' Create a child window with capCreateCaptureWindowA so you can display it in a picturebox.

        hHwnd = capCreateCaptureWindowA(iDevice, WS_VISIBLE Or WS_CHILD, 0, 0, 600, 480, picCapture.Handle, IntPtr.Zero)
        ' Connect to device
        If SendMessage(hHwnd, CAP_DRIVER_CONNECT, iDevice, IntPtr.Zero) Then

            ' Set the preview scale
            SendMessage(hHwnd, CAP_SET_SCALE, True, IntPtr.Zero)

            ' Set the preview rate in milliseconds
            SendMessage(hHwnd, CAP_SET_PREVIEWRATE, 66, IntPtr.Zero)

            ' Start previewing the image from the camera
            SendMessage(hHwnd, CAP_SET_PREVIEW, True, IntPtr.Zero)

            ' Resize window to fit in picturebox
            SetWindowPos(hHwnd, HWND_BOTTOM, 0, 0, picCapture.Width, picCapture.Height, SWP_NOMOVE Or SWP_NOZORDER)
        Else
            ' Error connecting to device close window
            DestroyWindow(hHwnd)

        End If
    End Sub

    Private Function btnSave_Click(ByVal sender As System.Object, ByVal e As System.EventArgs) Handles btnCapture.Click
        Dim data As IDataObject
        Dim bmap As Image
        ' Copy image to clipboard
        SendMessage(hHwnd, CAP_EDIT_COPY, 0, 0)

        ' Get image from clipboard and convert it to a bitmap
        data = Clipboard.GetDataObject()
        If data.GetDataPresent(GetType(System.Drawing.Bitmap)) Then
            bmap = CType(data.GetData(GetType(System.Drawing.Bitmap)), Image)
            picCapture.Image = bmap

            Dim saveFileDialog1 As New SaveFileDialog()
            saveFileDialog1.Filter = "Jpeg Image|*.jpg|Bitmap Image|*.bmp|Gif Image|*.gif"
            saveFileDialog1.Title = "Save an Image File"
            saveFileDialog1.FileName = "Image001"
            If saveFileDialog1.ShowDialog() = Windows.Forms.DialogResult.OK Then

                ' If the file name is not an empty string open it for saving.
                If saveFileDialog1.FileName <> "" Then
                    ' Saves the Image via a FileStream created by the OpenFile method.
                    Dim fs As System.IO.FileStream = CType(saveFileDialog1.OpenFile(), System.IO.FileStream)
                    picCapture.Image.Save(fs, System.Drawing.Imaging.ImageFormat.Jpeg)
                    fs.Close()
                End If
            End If

        End If
    End Function
    Public Function getImage() As String
        Dim bmap As Image
        Dim ms As New MemoryStream
        bmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
        Dim bytes() As Byte = ms.ToArray
        ' Dim image_base64String As String = Convert.ToBase64String(bytes)
        image_base64String = Convert.ToBase64String(bytes)
        'MsgBox(image_base64String)

        Return image_base64String
    End Function


    Private Sub frmcap_Leave(ByVal sender As Object, ByVal e As System.EventArgs) Handles Me.Leave
        ' Disconnect from device
        SendMessage(hHwnd, CAP_DRIVER_DISCONNECT, iDevice, 0)
        ' close window
        DestroyWindow(hHwnd)
    End Sub

    Private Sub frmCaptureWebCam_Load(sender As Object, e As EventArgs) Handles MyBase.Load
        OpenForm()
    End Sub
End Class

you will notice that I'm also trying to return the image via the image_base64 variable

Can someone help me with the code as I get the following error:

PInvokeStackImbalance was detected

Message: A call to PInvoke function 'GCOS3_Mobile_Host_Application!GCOS3_Mobile_Host_Application.frmCaptureWebCam::SendMessage' has unbalanced the stack. This is likely because the managed PInvoke signature does not match the unmanaged target signature. Check that the calling convention and parameters of the PInvoke signature match the target unmanaged signature.

David Heffernan
  • 601,492
  • 42
  • 1,072
  • 1,490
Privesh
  • 637
  • 2
  • 11
  • 19
  • 1
    P/Invoke declaration (specifically and/or for starters `SendMessage` you have immediate issue with) is likely to be fixed for 64-bit app. See [Declaring API functions in 64 bit Office](http://www.jkp-ads.com/articles/apideclarations.asp). – Roman R. Jan 12 '16 at 08:45
  • 1
    Please read the error message and do exactly what it says. – David Heffernan Jan 12 '16 at 08:54

2 Answers2

0

SendMessage declaration according to pinvoke should be like this

Declare Auto Function SendMessage Lib "user32.dll" (ByVal hWnd As IntPtr, ByVal msg As Integer, ByVal wParam As IntPtr, ByVal lParam As IntPtr) As IntPtr

Also see the tips for Overloads there.

  • In your code you have declared lParam, which provides additional message-specific information, as object.
  • And you are passing IntPtr.Zero, so I think using ByVal lParam As IntPtr will be more specific.
Yog
  • 112
  • 12
0

I used the emgu library and got it to return the base 64 string:

Imports Emgu.CV

Imports Emgu.CV.Util Imports System.IO

Public Class frmEmguCapture

Private imagecapture As Capture
Private imageCaptureReady As Boolean = False
Public b64 As String

Private Sub Timer1_Tick(sender As Object, e As EventArgs) Handles tmrUpdateImage.Tick
    tmrUpdateImage.Enabled = False

    If imageCaptureReady Then

        pbWebCamStream.Visible = True
        lblConnecting.Visible = False
        btnCapture.Enabled = True

        pbWebCamStream.Image = imagecapture.QueryFrame.Bitmap


        tmrUpdateImage.Enabled = True
    Else
        MessageBox.Show("Error connecting to camera.", "Error conecting to camera.", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Me.Close()
    End If

End Sub

Public Function btnCapture_Click(sender As Object, e As EventArgs) Handles btnCapture.Click
    tmrUpdateImage.Enabled = False

    pbWebCamStream.Visible = True
    lblConnecting.Visible = False
    btnCapture.Enabled = True

    pbWebCamStream.Image = imagecapture.QueryFrame.Bitmap
    Dim bmap As Image
    bmap = imagecapture.QueryFrame.Bitmap
    Dim ms As New MemoryStream
    bmap.Save(ms, System.Drawing.Imaging.ImageFormat.Jpeg)
    Dim bytes() As Byte = ms.ToArray
    Dim image_base64String As String = Convert.ToBase64String(bytes)


    image_base64String = Convert.ToBase64String(bytes)
    b64 = image_base64String
    imagecapture.Dispose()
    Me.Close()
    'MsgBox(image_base64String)
    Return image_base64String


End Function

Private Sub frmEmguCapture_Load(sender As Object, e As EventArgs) Handles MyBase.Load
    tmrLoad.Enabled = True
End Sub

Private Sub tmrLoad_Tick(sender As Object, e As EventArgs) Handles tmrLoad.Tick
    tmrLoad.Enabled = False

    Try
        imagecapture = New Capture
        imageCaptureReady = True
        tmrUpdateImage.Enabled = True
    Catch ex As Exception
        MessageBox.Show("Error connecting to camera.", "Error conecting to camera.", MessageBoxButtons.OK, MessageBoxIcon.Error)
        Me.Close()
    End Try

End Sub

End Class

Privesh
  • 637
  • 2
  • 11
  • 19