avi保存について教えて下さい。
aviファイルは作成できているのに中身が入ってません。
ソースを書きます。
void CAVIMonitorDlg::OnBnClickedButton1()
{
int nSts;
int nRet;
BOOL check;
CString msg;
DWORD timeCount = 0;
CString sTemp;
char cWk0[50];
char cPath[50];
SYSTEMTIME tm;
long LastFrame1= m_nRecFrame;
UINT Width=1024;
UINT Height=256;
int f;
for(f=0;f<m_nRecFrame; f++){
int ret=m_cameraControl->TransferFrame(f,image);
}
if(m_nRecFrame<=0){
msg = 保存できる画像が存在しません;
AfxMessageBox(msg,MB_OK|MB_ICONWARNING);
return;
}
nSts = m_cameraControl->OnLive(FALSE);
if(nSts!=PCC_ERROR_NOERROR){
msg = 再生モードに変更できませんでした;
AfxMessageBox(msg,MB_OK|MB_ICONWARNING);
return;
}
if(m_Execute_Live==TRUE){
::KillTimer(GetSafeHwnd(), TIMER_MODE_LIVE);
m_Execute_Live = FALSE;
}
BeginWaitCursor();
if(m_nRecFrame>0){
::GetLocalTime(&tm);
sprintf(cPath,c:%4.4d%2.2d%2.2d%,tm.wYear,tm.wMonth,tm.wDay);
CreateDirectory(cPath,NULL);
sprintf(cPath,c:%4.4d%2.2d%2.2d%\\test.avi,tm.wYear,tm.wMonth,tm.wDay);
nRet = m_cameraControl->IsColor((BOOL &)check);
if(check==TRUE){
nSts = outavi(cPath,image,LastFrame1,Width,Height);
if(nSts>0){
msg = ファイルに保存できませんでした;
AfxMessageBox(msg,MB_OK|MB_ICONWARNING);
EndWaitCursor();
return;
}
}
Sleep(3);
}
m_disp_status1.SetWindowText(ファイル保存終了);
msg = ファイルに保存しました;
AfxMessageBox(msg,MB_OK|MB_ICONINFORMATION);
EndWaitCursor();
}
int CAVIDlg::outavi(char *szFName,unsigned char *out_image,long
LastFrame1,UINT Width,UINT Height)
{
CFile file;
if(!file.Open(szFName,
CFile::modeCreate|CFile::modeWrite|CFile::typeBinary)){
return(-1);
}
HBITMAP hbm2;
BITMAPFILEHEADER bmphdr;
BITMAPINFOHEADER bmpihdr;
long nBufferSize = 1024*256*3;
byte *buffer = (byte*)malloc((sizeof(bmphdr)+sizeof(bmpihdr)
+nBufferSize));
bmphdr.bfType = ('M' << 8) | 'B';
bmphdr.bfSize = sizeof(bmphdr) + sizeof(bmpihdr) + nBufferSize;
bmphdr.bfReserved1 = 0;
bmphdr.bfReserved2 = 0;
bmphdr.bfOffBits = sizeof(bmphdr) + sizeof(bmpihdr);
//BMP情報
bmpihdr.biSize = 40L;
bmpihdr.biWidth = Width;
bmpihdr.biHeight = Height;
bmpihdr.biPlanes = 1;
bmpihdr.biBitCount = 24;
bmpihdr.biCompression = 0;
bmpihdr.biSizeImage = m_gnSizeBmpImage;
bmpihdr.biXPelsPerMeter = 0;
bmpihdr.biYPelsPerMeter = 0;
bmpihdr.biClrUsed = 0;
bmpihdr.biClrImportant = 0;
memcpy(buffer,&bmphdr,sizeof(bmphdr));
memcpy(buffer+sizeof(bmphdr),&bmpihdr,sizeof(bmpihdr));
for(UINT FileNo=0;FileNo<LastFrame1;FileNo++){
memcpy(
buffer+sizeof(bmphdr)+sizeof(bmpihdr),
out_image+FileNo*Width*Height*3,
nBufferSize);
GetHbitmapFromMemory((BYTE*)buffer,sizeof(bmphdr)+sizeof
(bmpihdr)+nBufferSize,&hbm2);
ImageRotate(&hbm2,ROTATE180FLIPX);
file.Write(&bmphdr,sizeof(bmphdr));
file.Write(&bmpihdr,sizeof(bmpihdr));
}
file.Close();
free(buffer);
return(0);
}
どこがいけないのでしょうか?
どなたかご教授下さい。
ただのビットマップを書き出すだけでAVIファイルになるのか激しく疑問ではありますが…
> file.Write(&bmphdr,sizeof(bmphdr));
> file.Write(&bmpihdr,sizeof(bmpihdr));
BITMAPFILEHEADERとBITMAPINFOHEADERを書き出していますが、肝心のデータはどこで書き
出しているのでしょう?
瀬戸っぷさん
ありがとうございます。
このソースではAVIにならないってことですか?
データの書き込みはどのようにしたらよいのでしょうか?
file.Write(&bmphdr,sizeof(bmphdr));
file.Write(&bmpihdr,sizeof(bmpihdr));
を書き替えたらできますか?
>このソースではAVIにならないってことですか?
書き出しているのがビットマップファイルの「ヘッダだけ」のようですけど……。
ヘッダだけで画像データは書き出していないですよね?
>データの書き込みはどのようにしたらよいのでしょうか?
AVIの出力に関しては自力で調べてください。
残念ながら私は複数枚のBMPデータからAVIファイルへの出力はやったことがありませんので。
最近(と言ってもここ3ヶ月以内)、どこかで「Webカメラの画像をAVIフアイルとして出力
したい」という内容の書き込みを見た記憶もありますが。
とりあえず、
m_cameraControlがなにものなのか、そのメンバ関数と思われるTransferFrame()の実装とか、
GetHbitmapFromMemory()やImageRotate()がなにをやっているのかも不明ですので。
# 名前から大体の予想ができなくもないですが…。
昔テスト用に作ったものです。
適当に修正して使用してください。
#include <stdio.h>
#include <stdlib.h>
#include <vfw.h>
#define LENG 10
#define WIDTH 160
#define HEIGHT 120
int WINAPI WinMain(HINSTANCE hInstance,HINSTANCE hPrevInstance,
LPSTR lpszCmdLine,int nCmdShow)
{
char fname[MAX_PATH];
int nIndex,nTotalHead,nFileSize;
AVISTREAMINFO si={streamtypeVIDEO,
mmioFOURCC('D','I','B',' '),
0,0,0,0,1,30,0,LENG,0,0,(DWORD)-
1,0,{0,0,WIDTH,HEIGHT},0,0,ビデオ};
FILE *fp;
LPBITMAPINFOHEADER pBMIHeader=NULL;
PAVIFILE pAVIFile;
PAVISTREAM pAVIStream;
AVIFileInit();
if (AVIFileOpen(&pAVIFile,TEST01.AVI,
OF_CREATE |
OF_WRITE | OF_SHARE_DENY_NONE,NULL)!=0)
{
return 0;
}
if (AVIFileCreateStream(pAVIFile,&pAVIStream,&si)!=0)
{
return 0;
}
for (nIndex=0;nIndex<LENG;nIndex++)
{
wsprintf(fname,TEST%02d.BMP,nIndex);
if ((fp=fopen(fname,rb))==NULL)
{
break;
}
if (fseek(fp,0,SEEK_END)!=0)
{
fclose(fp);
break;
}
if ((nFileSize=ftell(fp))==-1)
{// サイズが不正
fclose(fp);
break;
}
if (fseek(fp,sizeof(BITMAPFILEHEADER),SEEK_SET)!=0)
{//
fclose(fp);
break;
}
// ヘッダー部分は除外
nFileSize -= sizeof(BITMAPFILEHEADER);
// ビットマップヘッダーの取得
pBMIHeader=(LPBITMAPINFOHEADER)realloc(pBMIHeader,nFileSize);
if (fread(pBMIHeader,nFileSize,1,fp)!=1)
{// 取得失敗
fclose(fp);
break;
}
fclose(fp);
if (pBMIHeader->biClrUsed==0)
{
switch (pBMIHeader->biBitCount)
{
case 1:nTotalHead=8;
break;
case 4:nTotalHead=64;
break;
case 8:nTotalHead=1024;
break;
case 24:nTotalHead=0;
break;
case 16:
case 32:nTotalHead=pBMIHeader-
>biCompression==BI_RGB?12:0;break;
default:return 0;
}
}
else
{
nTotalHead=pBMIHeader->biClrUsed*4;
}
nTotalHead+=sizeof(BITMAPINFOHEADER);
if (AVIStreamSetFormat
(pAVIStream,nIndex,pBMIHeader,nTotalHead)!=0)
{
break;
}
if (AVIStreamWrite(pAVIStream,
nIndex,
1,
(LPBYTE)
pBMIHeader+nTotalHead,
nFileSize-
nTotalHead,
AVIIF_KEYFRAME,
NULL,
NULL)!=0)
{
break;
}
}
AVIStreamRelease(pAVIStream);
AVIFileRelease(pAVIFile);
AVIFileExit();
if (pBMIHeader!=NULL)
{
free(pBMIHeader);
}
return 0;
}
> このソースではAVIにならないってことですか?
> データの書き込みはどのようにしたらよいのでしょうか?
AIVファイルのフォーマットをきちんと調べてそれに従って書き出しているなら
再生も出来るはずだと思います。
再生で来ていない時点で間違っていると判断できると思います。
御自身が何処まで調べてやっているのかの説明が全く無いので
わかりませんが、AVIファイルのフォーマットが理解できていないので
あれば、きちんと理解してからプログラムを書くことをお勧めします。
あと、フォーマットの仕様書が英語しかなくても
辞書を片手に頑張れば読めると思います。
この手の技術文書は文法は素直な物しか使いませんし。
ソフトウエアに限らずですけれど、最新の情報は英語で
提供されているケースが結構多いので英語は必須と思ったほうが良いです。