2

I am using Aaron Ballman's Windows Functionality Suite to capture video from my webcam. It works fine but ... webcam.startpreview starts the camera images appearing and webcam.stoppreview does as it says and stops the video.

My question is that, after stoppreview I am left with a still image in the canvas control and I need to know how to save that image to disk - preferably as a jpg file.

mjdth
  • 6,536
  • 6
  • 37
  • 44
Alan McTavish
  • 121
  • 1
  • 8

1 Answers1

1

The canvas control doesn't actually contain the image in this case; it's only used to specify the dimensions and parent of a system-managed window that gets displayed directly on top of the Canvas.

To grab the current frame you'll need to capture the contents of this system-managed window.

e.g. add this function to the WebCamWFS module:

Function CaptureFrame(SourceCanvas As Canvas) As Picture
  Declare Function GetDC Lib "User32" (HWND As Integer) As Integer
  Declare Function BitBlt Lib "GDI32" (DCdest As Integer, xDest As Integer, yDest As Integer, nWidth As Integer, _
      nHeight As Integer, DCdource As Integer, xSource As Integer, ySource As Integer, rasterOp As Integer) As Boolean
  Declare Function ReleaseDC Lib "User32" (HWND As Integer, DC As Integer) As Integer

  Const SRCCOPY = &h00CC0020
  Const CAPTUREBLT = &h40000000

  Dim hDC, w, h As Integer
  hDC = GetDC(mWnd)
  w = SourceCanvas.Width
  h = SourceCanvas.Height
  x = SourceCanvas.Left + SourceCanvas.Window.Left
  y = SourceCanvas.Top + SourceCanvas.Window.Top

  Dim capture As New Picture(w, h, 24)
  Call BitBlt(Capture.Graphics.Handle(1), 0, 0, w, h, hDC, 0, 0, SRCCOPY Or CAPTUREBLT)
  Call ReleaseDC(mWnd, hDC)
  Return capture
End Function

Use the DrawInto method of the Canvas control to copy the image to a Picture object, then save the Picture to a file:

  Dim mypic As New Picture(TargetCanvas.Width, TargetCanvas.Height, 32)
  TargetCanvas.Drawinto(mypic.Graphics, 0, 0)
  Dim saveto As FolderItem = GetSaveFolderItem("", "mypic.jpg")
  mypic.Save(saveto, Picture.SaveAsJPEG)

Andrew Lambert
  • 1,869
  • 1
  • 17
  • 31
  • Thanks Amazed but I'm afraid it doesn't work ... all I get is a white rectangle. I did change the last line though to :- saveto.SaveAsJPEG mypic. – Alan McTavish Dec 25 '13 at 08:39
  • Try saving the canvas before calling `StopPreview`. – Andrew Lambert Dec 26 '13 at 02:48
  • Hi Amazed, Yes, I had tried that and had tried saving in various placesto different graphics objects such as another canvas and so on. It is definitely 'DrawInto' that isn't working and I have no idea why. I've tried changing the window type and all sorts. Any other ideas? – Alan McTavish Dec 26 '13 at 07:27
  • 1
    Hi again Amazed, As always, thanks very much for your help in this matter. I found a bit of Delphi code which I was able to convert. It used the API calls similar to Aarons code and I worked out how to use 'WM_CAP_GRAB_FRAME' to put the image on the clipboard. From there on in it was easy to save it as a picture using Realbasic's Clipboard object. I've given you the credit because you deserve it - you inspire me! Cheers, Alan ... – Alan McTavish Dec 26 '13 at 08:20
  • Alan, it would be great if you could post the code you came up with as an answer. – Paul Lefebvre Jan 14 '14 at 15:16
  • @PaulLefebvre, `BitBlt` the window returned by `capCreateCaptureWindow` into a RB Picture. The Canvas control in Aaron Ballman's code is there only as a stand-in for this system-managed window, it's never actually drawn to. – Andrew Lambert May 19 '14 at 17:39