使用Directshow编写的拍照软件,在保存为bmp文件时,保存下来的文件是损坏的。各位大大能帮我看看我代码哪里有问题吗

zhou45214284 2015-03-18 04:56:03
不知道是文件那个信息数据设置有误,麻烦帮忙看下吧
bool CCaptureVideo::CaptureBitmap1(const char* outfile)
{

CComQIPtr< IBasicVideo, &IID_IBasicVideo >pBasicVideo(m_pGB);
if (pBasicVideo)
{
long bitmapSize=0;
//首先获得图像大小
if(SUCCEEDED(pBasicVideo->GetCurrentImage(&bitmapSize,0)))
{
bool pass=false;
//分配图像帧内存
unsigned char*buffer=new unsigned char[bitmapSize];
//获取图像帧数据
if(SUCCEEDED(pBasicVideo->GetCurrentImage(&bitmapSize,(long*)buffer)))
{
BITMAPFILEHEADER hdr;
LPBITMAPINFOHEADER ipbi;
ipbi=(LPBITMAPINFOHEADER)buffer;
int nColors=1<<ipbi->biBitCount;
//if(nColors>256)
hdr.bfType = 'BM' ;
hdr.bfSize =bitmapSize+sizeof(hdr);
hdr.bfReserved1 =0;
hdr.bfReserved2 =0;
hdr.bfOffBits =(DWORD)
(sizeof(BITMAPFILEHEADER)+ipbi->biSize+nColors*sizeof(RGBQUAD));
HANDLE hf = CreateFile(LPCTSTR(outfile), GENERIC_WRITE, FILE_SHARE_WRITE, NULL, CREATE_ALWAYS, 0, NULL);
DWORD dwWritten = 0;

WriteFile( hf, &hdr, sizeof( hdr ), &dwWritten, NULL );
dwWritten=0;
WriteFile( hf, &ipbi, sizeof( ipbi ), &dwWritten, NULL );
dwWritten=0;
WriteFile(hf, buffer, bitmapSize, &dwWritten, NULL );
CloseHandle( hf );
pass=true;
}
//delete[]burfer;
return pass;
}
}
}

上面是代码,m_pGB变量是定义的IGraphBuilder* m_pGB; //滤波器链表管理器
...全文
171 2 打赏 收藏 转发到动态 举报
写回复
用AI写文章
2 条回复
切换为时间正序
请发表友善的回复…
发表回复
zhou45214284 2015-03-20
  • 打赏
  • 举报
回复
引用 1 楼 xjq2003 的回复:
打开摄像头

#include <vfw.h>
HWND hWndC,ghWndCap;
void __fastcall TfmGoodsPhotoGet::sbCheckVideoClick(TObject *Sender)
{
  bool bVFWFlag;
  int iVFWCount;

  if(!bCheckVideoEnable)
  {//探杆打开
    hWndC = Panel8->Handle;
    //创建捕获窗,其中hWnd为主窗口句柄
    ghWndCap = capCreateCaptureWindow("Capture Window",WS_CHILD|WS_VISIBLE,
                                    0,0,352,298,hWndC,0);

    bVFWFlag = false;
    iVFWCount = 0;
    while((iVFWCount<1000)&&(bVFWFlag==false))
    {
      bVFWFlag = capDriverConnect(ghWndCap,0);
      iVFWCount++;
    }
    if(bVFWFlag==true)
    {
      CAPDRIVERCAPS caps;
      capDriverGetCaps(ghWndCap,sizeof(caps),&caps);
      if(caps.fHasOverlay) capOverlay(ghWndCap,TRUE);

      capPreviewScale(ghWndCap,1);
      capPreviewRate(ghWndCap,1000/24);   //   设置Preview模式的显示速率
      capPreview(ghWndCap,TRUE);   //启动Preview模式
      bCheckVideoEnable = true;
      sbCheckVideo->Caption = "关闭探杆";
      sbCapture->Enabled = true;
   }
  }
  else
  {//探杆关闭
    if(ghWndCap)
    {
      capPreview(ghWndCap,false);
      capCaptureStop(ghWndCap);
      capCaptureAbort(ghWndCap);
      capDriverDisconnect(ghWndCap);
      ::DestroyWindow(ghWndCap);
      ghWndCap=NULL;
      bCheckVideoEnable = false;
      sbCheckVideo->Caption = "打开探杆";
      sbCapture->Enabled = false;
    }
  }
}
//---------------------------------------------------------------------------

抓拍,仅供参考


void __fastcall TfmGoodsPhotoGet::sbCaptureClick(TObject *Sender)
{
  TJPEGImage   *j=new   TJPEGImage;
  Graphics::TBitmap   *b=new   Graphics::TBitmap;
  AnsiString asSaveFile;

  if(!bCheckVideoEnable)
  {
    lbOpInfo->Caption = "探杆未打开";
    return;
  }
  if(ghWndCap)
  {
    int i;
    i=0;
    try
    {
      asSaveFile = fmMain->asPhotoDir + "\\photo.bmp";
      capFileSaveDIB(ghWndCap,asSaveFile.c_str());
      i=1;
      b->LoadFromFile(asSaveFile);
      i=2;
      j->Assign(b);
      j->CompressionQuality=100;       //等级太高有可能压缩出错!
      j->Compress();
      i=3;
      ms_Temp->Position = 0;
      j->SaveToStream(ms_Temp);
      i=4;
      ms_Temp->Position = 0;
      jpgTemp->LoadFromStream(ms_Temp);
      i=5;
      imgComm->Picture->Assign(jpgTemp);
      i=6;
      lbOpInfo->Caption = "";
    }
    catch(...)
    {
      lbOpInfo->Caption = "抓拍失败!"+ AnsiString(i);
    }
  }
  else
  {
    lbOpInfo->Caption = "探杆未打开";
  }
  delete   b;
  delete   j;
}
//---------------------------------------------------------------------------
这个方法我试过的,如果是preview模式可以使用,但是现在平板上要用overlay模式,有问题所以我改用的directshow。
xjq2003 2015-03-20
  • 打赏
  • 举报
回复
打开摄像头

#include <vfw.h>
HWND hWndC,ghWndCap;
void __fastcall TfmGoodsPhotoGet::sbCheckVideoClick(TObject *Sender)
{
  bool bVFWFlag;
  int iVFWCount;

  if(!bCheckVideoEnable)
  {//探杆打开
    hWndC = Panel8->Handle;
    //创建捕获窗,其中hWnd为主窗口句柄
    ghWndCap = capCreateCaptureWindow("Capture Window",WS_CHILD|WS_VISIBLE,
                                    0,0,352,298,hWndC,0);

    bVFWFlag = false;
    iVFWCount = 0;
    while((iVFWCount<1000)&&(bVFWFlag==false))
    {
      bVFWFlag = capDriverConnect(ghWndCap,0);
      iVFWCount++;
    }
    if(bVFWFlag==true)
    {
      CAPDRIVERCAPS caps;
      capDriverGetCaps(ghWndCap,sizeof(caps),&caps);
      if(caps.fHasOverlay) capOverlay(ghWndCap,TRUE);

      capPreviewScale(ghWndCap,1);
      capPreviewRate(ghWndCap,1000/24);   //   设置Preview模式的显示速率
      capPreview(ghWndCap,TRUE);   //启动Preview模式
      bCheckVideoEnable = true;
      sbCheckVideo->Caption = "关闭探杆";
      sbCapture->Enabled = true;
   }
  }
  else
  {//探杆关闭
    if(ghWndCap)
    {
      capPreview(ghWndCap,false);
      capCaptureStop(ghWndCap);
      capCaptureAbort(ghWndCap);
      capDriverDisconnect(ghWndCap);
      ::DestroyWindow(ghWndCap);
      ghWndCap=NULL;
      bCheckVideoEnable = false;
      sbCheckVideo->Caption = "打开探杆";
      sbCapture->Enabled = false;
    }
  }
}
//---------------------------------------------------------------------------

抓拍,仅供参考


void __fastcall TfmGoodsPhotoGet::sbCaptureClick(TObject *Sender)
{
  TJPEGImage   *j=new   TJPEGImage;
  Graphics::TBitmap   *b=new   Graphics::TBitmap;
  AnsiString asSaveFile;

  if(!bCheckVideoEnable)
  {
    lbOpInfo->Caption = "探杆未打开";
    return;
  }
  if(ghWndCap)
  {
    int i;
    i=0;
    try
    {
      asSaveFile = fmMain->asPhotoDir + "\\photo.bmp";
      capFileSaveDIB(ghWndCap,asSaveFile.c_str());
      i=1;
      b->LoadFromFile(asSaveFile);
      i=2;
      j->Assign(b);
      j->CompressionQuality=100;       //等级太高有可能压缩出错!
      j->Compress();
      i=3;
      ms_Temp->Position = 0;
      j->SaveToStream(ms_Temp);
      i=4;
      ms_Temp->Position = 0;
      jpgTemp->LoadFromStream(ms_Temp);
      i=5;
      imgComm->Picture->Assign(jpgTemp);
      i=6;
      lbOpInfo->Caption = "";
    }
    catch(...)
    {
      lbOpInfo->Caption = "抓拍失败!"+ AnsiString(i);
    }
  }
  else
  {
    lbOpInfo->Caption = "探杆未打开";
  }
  delete   b;
  delete   j;
}
//---------------------------------------------------------------------------

604

社区成员

发帖
与我相关
我的任务
社区描述
C++ Builder VCL组件使用和开发
社区管理员
  • VCL组件使用和开发社区
加入社区
  • 近7日
  • 近30日
  • 至今
社区公告
暂无公告

试试用AI创作助手写篇文章吧