解决方案

使用USB摄像头(Webcam)拍照

seo靠我 2023-09-25 04:34:02

你想不想使用webcam来自己拍张照片呢?

首先你要通过capCreateCaptureWindow创建Capture 窗口,使用capDriverConnect连接WebCam,调用capSetVidSEO靠我eoFormat设置视频格式,通过capSetCallbackOnFrame设置CallBack函数。

int CWebCamCamera::StartWebCam(HWND hParent, int SEO靠我nWidth, int nHeight)

{

 TCHAR szName[MAX_PATH] = {0};

 TCHAR szVer[MAX_PATH]  = {0};

BOOL bRet = capGetDriSEO靠我verDescription(0, szName, MAX_PATH, szVer, MAX_PATH);

 if (!bRet)

 {

  return -1;

 }

m_hWnd = capCreateCaptureSEO靠我Window(szName, WS_VISIBLE | WS_CHILD, 0, 0, nWidth, nHeight, hParent, 0);

if (capDriverConnect(m_hWndSEO靠我, 0))

 {

        capPreviewRate(m_hWnd, 66);

        capPreview(m_hWnd, TRUE);

  capPreviewScale(m_hWnd, TRUE);

BITMAPINFO bSEO靠我itmapinfo;

        bitmapinfo.bmiHeader.biSize     = sizeof(bitmapinfo.bmiHeader);

bitmapinfo.bmiHeader.biWidtSEO靠我h    = nWidth;

        bitmapinfo.bmiHeader.biHeight   = nHeight;

        bitmapinfo.bmiHeader.biPlanes   = 1;

bitmapinSEO靠我fo.bmiHeader.biBitCount = 24;

        capSetVideoFormat(m_hWnd, &bitmapinfo, sizeof(bitmapinfo));

capSetCallbaSEO靠我ckOnFrame(m_hWnd, FrameCallbackProc);

  SetWindowPos(m_hWnd, NULL, 0, 0, nWidth,

nHeight, SWP_NOZORDER |SEO靠我 SWP_NOMOVE);

 }

 return 0;

}

这时你就可以开始Capture视频了.

获取视频帧图像数据保存为图像,可以有两种方式:

1.在CallBack函数里面获取实时帧数据。

LRESULT WINSEO靠我API CWebCamCamera::FrameCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)

{

    if (!hWnd) return FALSE;

// lpVHdrSEO靠我->lpData, Dib bits data(after BITMAPINFOHEADER)

 // lpVHdr->dwBytesUsed, Dib size

//Create bitmap from SEO靠我a frame data

 HANDLE hFile = CreateFile(L"F://Frame.bmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,   

FILE_ASEO靠我TTRIBUTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

 BITMAPINFOHEADER bih;

    BITMAPFILEHEADER bfh;

ZeroMemSEO靠我ory(&bfh, sizeof(bfh));

 ZeroMemory(&bih, sizeof(bih));

 DWORD dwSize, dwWritten;

dwSize = capGetVideoForSEO靠我matSize(hWnd);

 capGetVideoFormat(hWnd, &bih, dwSize);

    bfh.bfType = MB;  // Little-endian for "MB".

bfh.SEO靠我bfSize = sizeof(BITMAPFILEHEADER) + sizeof(BITMAPINFOHEADER) + lpVHdr->dwBytesUsed;

bfh.bfReserved1 =SEO靠我 0;

 bfh.bfReserved2 = 0;   

bfh.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEASEO靠我DER);

 WriteFile(hFile, &bfh, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);

WriteFile(hFile, &bih, sizeoSEO靠我f(BITMAPINFOHEADER), &dwWritten, NULL);

WriteFile(hFile, lpVHdr->lpData, lpVHdr->dwBytesUsed, &dwWritSEO靠我ten, NULL);

 CloseHandle(hFile);   

    return (LRESULT) TRUE ;

}

2.也可以通过capGrabFrame和capEditCopy把帧数据保存到剪贴板里,然后通SEO靠我过剪贴板获取图像。

然后把位图数据保存为位图文件。

  HBITMAP hBitmap = NULL;

  capGrabFrame(m_hWnd);

  capEditCopy(m_hWnd);

OpenClipboarSEO靠我d(NULL);

  hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);

  CloseClipboard();

就是这么简单。封装成一个class,代码如下:

//WebSEO靠我CamCamera.h

#pragma once

#include <Vfw.h>

class CWebCamCamera

{

public:

 CWebCamCamera(void);

virtual ~CWebCSEO靠我amCamera(void);

 int StartWebCam(HWND hParent, int nWidth, int nHeight);

static LRESULT WINAPI FrameCalSEO靠我lbackProc(HWND hWnd, LPVIDEOHDR lpVHdr);

 int TakeSnapshot(IStream* pIPicture);

int TakeSnapshot(TCHAR*SEO靠我 szPicture);

 int CloseWebCam(void);

private:

 PBITMAPINFO CreateBitmapInfoStruct(HBITMAP hBmp);

HWND m_hWSEO靠我ndParent;

 HWND m_hWnd;

};

//WebCamCamera.cpp

#include "stdafx.h"

#include "WebCamCamera.h"

CWebCamCamera::SEO靠我CWebCamCamera(void)

{

 m_hWndParent = NULL;

 m_hWnd = NULL;

}

CWebCamCamera::~CWebCamCamera(void)

{

}

int CWebSEO靠我CamCamera::StartWebCam(HWND hParent, int nWidth, int nHeight)

{

 TCHAR szName[MAX_PATH] = {0};

TCHAR szVSEO靠我er[MAX_PATH]  = {0};

 BOOL bRet = capGetDriverDescription(0, szName, MAX_PATH, szVer, MAX_PATH);

if (!bSEO靠我Ret)

 {

  return -1;

 }

m_hWnd = capCreateCaptureWindow(szName, WS_VISIBLE | WS_CHILD, 0, 0, nWidth, nHeightSEO靠我, hParent, 0);

 if (capDriverConnect(m_hWnd, 0))

 {

        capPreviewRate(m_hWnd, 66);

        capPreview(m_hWnd, TRUE);

cSEO靠我apPreviewScale(m_hWnd, TRUE);

        BITMAPINFO bitmapinfo;

bitmapinfo.bmiHeader.biSize     = sizeof(bitmapinSEO靠我fo.bmiHeader);

        bitmapinfo.bmiHeader.biWidth    = nWidth;

        bitmapinfo.bmiHeader.biHeight   = nHeight;

bitSEO靠我mapinfo.bmiHeader.biPlanes   = 1;

        bitmapinfo.bmiHeader.biBitCount = 24;

capSetVideoFormat(m_hWnd, &bitSEO靠我mapinfo, sizeof(bitmapinfo));

        capSetCallbackOnFrame(m_hWnd, FrameCallbackProc);

SetWindowPos(m_hWnd, NSEO靠我ULL, 0, 0, nWidth,

    nHeight, SWP_NOZORDER | SWP_NOMOVE);

 }

 return 0;

}

int CWebCamCamera::CloseWebCam(voidSEO靠我)

{

 if (m_hWnd)

 {

  capDriverDisconnect(m_hWnd);

  m_hWnd = NULL;

 }

 return 0;

}

LRESULT WINAPI CWebCamCamera::FraSEO靠我meCallbackProc(HWND hWnd, LPVIDEOHDR lpVHdr)

{

    if (!hWnd) return FALSE;

// lpVHdr->lpData, Dib bits datSEO靠我a(after BITMAPINFOHEADER)

 // lpVHdr->dwBytesUsed, Dib size

 /* Create bitmap from a frame data

HANDLE hFSEO靠我ile = CreateFile(L"F://Frame.bmp", GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,

FILE_ATTRIBUTE_NORMAL | FILSEO靠我E_FLAG_SEQUENTIAL_SCAN, NULL);

 BITMAPINFOHEADER bih;

    BITMAPFILEHEADER bfh;

ZeroMemory(&bfh, sizeof(bfh)SEO靠我);

 ZeroMemory(&bih, sizeof(bih));

 DWORD dwSize, dwWritten;

 dwSize = capGetVideoFormatSize(hWnd);

capGetVSEO靠我ideoFormat(hWnd, &bih, dwSize);

    bfh.bfType = MB;  // Little-endian for "MB".

bfh.bfSize = sizeof(BITMASEO靠我PFILEHEADER) + sizeof(BITMAPINFOHEADER) + lpVHdr->dwBytesUsed;

 bfh.bfReserved1 = 0;   

bfh.bfReserved2 = SEO靠我0;

 bfh.bfOffBits = (DWORD)sizeof(BITMAPFILEHEADER) + (DWORD)sizeof(BITMAPINFOHEADER);

WriteFile(hFile,SEO靠我 &bfh, sizeof(BITMAPFILEHEADER), &dwWritten, NULL);

WriteFile(hFile, &bih, sizeof(BITMAPINFOHEADER), SEO靠我&dwWritten, NULL);

 WriteFile(hFile, lpVHdr->lpData, lpVHdr->dwBytesUsed, &dwWritten, NULL);

CloseHandlSEO靠我e(hFile);

 */

    return (LRESULT) TRUE ;

}

int CWebCamCamera::TakeSnapshot(IStream* pIPicture)

{

if (pIPictureSEO靠我 == NULL)

 {

  return -1;

 }

 HBITMAP hBitmap = NULL;

 if (m_hWnd)

 {

  capGrabFrame(m_hWnd);

  capEditCopy(m_hWnd);

OpeSEO靠我nClipboard(NULL);

  hBitmap = (HBITMAP)GetClipboardData(CF_BITMAP);

  CloseClipboard();

static BOOL bShow =SEO靠我 TRUE;

  if (bShow)

  {

   ShowWindow(m_hWnd, SW_HIDE);

   bShow = FALSE;

  }

  else

  {

   ShowWindow(m_hWnd, SW_SHOW);

bShow =SEO靠我 TRUE;

  }

  capPreview(m_hWnd, TRUE);

 }

 if (hBitmap)

 {

  LARGE_INTEGER liZero;

ZeroMemory(&liZero, sizeof(liZeroSEO靠我));

  BITMAPINFO bmi;

        BITMAPFILEHEADER bfh;

        ZeroMemory(&bfh, sizeof(bfh));

  ZeroMemory(&bmi, sizeof(bmi));

DSEO靠我WORD dwSize;

  dwSize = capGetVideoFormatSize(m_hWnd);

  capGetVideoFormat(m_hWnd,&bmi,dwSize);

LPBITMAPINFSEO靠我OHEADER pbih = (LPBITMAPINFOHEADER)&bmi;

LPBYTE lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizSEO靠我eImage);

  if (!lpBits) return -2;

  HDC hDC = GetDC(NULL);

if (!GetDIBits(hDC, hBitmap, 0, (WORD)pbih->biHSEO靠我eight, lpBits, (LPBITMAPINFO)&bmi,

   DIB_RGB_COLORS))

  {

   return -3;

  }

bfh.bfType = MB;  // Little-endian forSEO靠我 "MB".

        bfh.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +

                 pbih->biSize + pbih->biClrUsed

* sizeof(RGBQUADSEO靠我) + pbih->biSizeImage);

        bfh.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +

pbih->biSize + pbih->biClrUSEO靠我sed

                    * sizeof (RGBQUAD);

  pIPicture->Seek(liZero, STREAM_SEEK_SET, NULL);

pIPicture->Write(&bfh, sizeof(bSEO靠我fh), NULL);

  pIPicture->Write((LPVOID)pbih, sizeof(BITMAPINFOHEADER)

+ pbih->biClrUsed * sizeof (RGBQUASEO靠我D), NULL);

  pIPicture->Write(lpBits, pbih->biSizeImage, NULL);

  GlobalFree((HGLOBAL)lpBits);

 }

 return 0;

}

iSEO靠我nt CWebCamCamera::TakeSnapshot(TCHAR* szPicture)

{

 if ( NULL == szPicture )

 {

  return -1;

 }

HBITMAP hBitmapSEO靠我 = NULL;

 if ( m_hWnd )

 {

  capGrabFrame(m_hWnd);

  capEditCopy(m_hWnd);

  OpenClipboard(NULL);

hBitmap = (HBITMASEO靠我P)GetClipboardData(CF_BITMAP);

  CloseClipboard();

  static BOOL bShow = TRUE;

  if (bShow)

  {

ShowWindow(m_hWndSEO靠我, SW_HIDE);

   bShow = FALSE;

  }

  else

  {

   ShowWindow(m_hWnd, SW_SHOW);

   bShow = TRUE;

  }

  capPreview(m_hWnd, TRUE);

 }

iSEO靠我f ( hBitmap )

 {

  HANDLE hFile = CreateFile(szPicture, GENERIC_WRITE, 0, NULL, CREATE_ALWAYS,   

FILE_ATTRIBSEO靠我UTE_NORMAL | FILE_FLAG_SEQUENTIAL_SCAN, NULL);

  LARGE_INTEGER liZero;

ZeroMemory(&liZero, sizeof(liZeroSEO靠我));

  BITMAPINFO bmi;

        BITMAPFILEHEADER bfh;

        ZeroMemory(&bfh, sizeof(bfh));

  ZeroMemory(&bmi, sizeof(bmi));

DSEO靠我WORD dwSize;

  dwSize = capGetVideoFormatSize(m_hWnd);

  capGetVideoFormat(m_hWnd,&bmi,dwSize);

LPBITMAPINFSEO靠我OHEADER pbih = (LPBITMAPINFOHEADER)&bmi;

LPBYTE lpBits = (LPBYTE) GlobalAlloc(GMEM_FIXED, pbih->biSizSEO靠我eImage);

  if (!lpBits) return -2;

  HDC hDC = GetDC(NULL);

if (!GetDIBits(hDC, hBitmap, 0, (WORD)pbih->biHSEO靠我eight, lpBits, (LPBITMAPINFO)&bmi,

   DIB_RGB_COLORS))

  {

   return -3;

  }

bfh.bfType = MB;  // Little-endian forSEO靠我 "MB".

        bfh.bfSize = (DWORD) (sizeof(BITMAPFILEHEADER) +

                 pbih->biSize + pbih->biClrUsed

* sizeof(RGBQUADSEO靠我) + pbih->biSizeImage);

        bfh.bfOffBits = (DWORD) sizeof(BITMAPFILEHEADER) +

pbih->biSize + pbih->biClrUSEO靠我sed

                    * sizeof (RGBQUAD);

  WriteFile(hFile, &bfh, sizeof(bfh), &dwWritten, NULL);

WriteFile(hFile, (LPVOIDSEO靠我)pbih, sizeof(BITMAPINFOHEADER)+ pbih->biClrUsed * sizeof (RGBQUAD), &dwWritten, NULL);

WriteFile(hFiSEO靠我le, lpBits, pbih->biSizeImage, &dwWritten, NULL);

  GlobalFree((HGLOBAL)lpBits);

  if ( hFile )

  {

CloseHandlSEO靠我e(hFile);

  }

 }

 else

 {

  return -4;

 }

 return 0;

}

PBITMAPINFO CWebCamCamera::CreateBitmapInfoStruct(HBITMAP hBmp)SEO靠我

{

    BITMAP bmp;

    PBITMAPINFO pbmi;

    WORD    cClrBits;

// Retrieve the bitmap color format, width, and heightSEO靠我.

    if (!GetObject(hBmp, sizeof(BITMAP), (LPSTR)&bmp))

     return NULL;

// Convert the color format to a counSEO靠我t of bits.

    cClrBits = (WORD)(bmp.bmPlanes * bmp.bmBitsPixel);

    if (cClrBits == 1)

        cClrBits = 1;

else if (SEO靠我cClrBits <= 4)

        cClrBits = 4;

    else if (cClrBits <= 8)

        cClrBits = 8;

    else if (cClrBits <= 16)

cClrBits = 16SEO靠我;

    else if (cClrBits <= 24)

        cClrBits = 24;

    else cClrBits = 32;

// Allocate memory for the BITMAPINFO struSEO靠我cture. (This structure

    // contains a BITMAPINFOHEADER structure and an array of RGBQUAD

// data structSEO靠我ures.)

     if (cClrBits != 24)

         pbmi = (PBITMAPINFO) LocalAlloc(LPTR,

                    sizeof(BITMAPINFOHEADER) +

sizeof(RGBQUSEO靠我AD) * (1<< cClrBits));

     // There is no RGBQUAD array for the 24-bit-per-pixel format.

     else

pbmi = (PBITMSEO靠我APINFO) LocalAlloc(LPTR,

                    sizeof(BITMAPINFOHEADER));

// Initialize the fields in the BITMAPINFO structuSEO靠我re.

    pbmi->bmiHeader.biSize = sizeof(BITMAPINFOHEADER);

    pbmi->bmiHeader.biWidth = bmp.bmWidth;

pbmi->bmiSEO靠我Header.biHeight = bmp.bmHeight;

    pbmi->bmiHeader.biPlanes = bmp.bmPlanes;

pbmi->bmiHeader.biBitCount = SEO靠我bmp.bmBitsPixel;

    if (cClrBits < 24)

        pbmi->bmiHeader.biClrUsed = (1<<cClrBits);

// If the bitmap is not SEO靠我compressed, set the BI_RGB flag.

    pbmi->bmiHeader.biCompression = BI_RGB;

// Compute the number of byteSEO靠我s in the array of color

    // indices and store the result in biSizeImage.

// For Windows NT, the width mSEO靠我ust be DWORD aligned unless

    // the bitmap is RLE compressed. This example shows this.

// For Windows 9SEO靠我5/98/Me, the width must be WORD aligned unless the

    // bitmap is RLE compressed.

pbmi->bmiHeader.biSizeSEO靠我Image = ((pbmi->bmiHeader.biWidth * cClrBits +31) & ~31) /8

                                  * pbmi->bmiHeader.biHeight;

// Set biClrImSEO靠我portant to 0, indicating that all of the

    // device colors are important.

pbmi->bmiHeader.biClrImportanSEO靠我t = 0;

     return pbmi;

 }

“SEO靠我”的新闻页面文章、图片、音频、视频等稿件均为自媒体人、第三方机构发布或转载。如稿件涉及版权等问题,请与 我们联系删除或处理,客服邮箱:html5sh@163.com,稿件内容仅为传递更多信息之目的,不代表本网观点,亦不代表本网站赞同 其观点或证实其内容的真实性。

网站备案号:浙ICP备17034767号-2