
BMPファイルからAVIファイルを作成する際のAVIStreamWriteの使用方法を教えてください。
AVIStreamWriteを使用して1枚ずつBMPファイルをAVIファイルに書き込むことはできたのですが複数のBMPファイルを一度にAVIファイルに書き込むことはできるのでしょうか。
AVIStreamWriteのパラメータに「書き込むサンプル数」の指定など複数ファイルの登録ができそうな感じがあるのですがうまくいきません。
おそらくパラメータの指定方法が誤っているのだと思うのですが、具体的な例などがありましたら教えてください。
A 回答 (3件)
- 最新から表示
- 回答順に表示
No.3
- 回答日時:
こんばんは。
動画が出来上がらないと言う事でしょうか?
AVIStreamWrite()の2番目のパラメータにAVIストリームの書き込む位置を渡していないなど。
//AVIストリームの長さを取る(次に書き込む位置にもなる)
LONG lLen = ::AVIStreamLength(pAVIStream);
HRESULT hResult = ::AVIStreamWrite(pAVIStream, lLen, 1, dib.dsBm.bmBits, dib.dsBmih.biSizeImage, AVIIF_KEYFRAME, NULL, NULL);
昔参考にしたサイトを紹介しておきます。
http://eternalwindows.jp/winmm/avi/avi07.html
以下は、1秒間30コマ(フレーム)で黒→赤にジュワ~っと変色するAVIファイル作成プログラムをしてみました。
アラもあるかと思いますが、参考程度に。
#include<windows.h>
#include<vfw.h>
#pragma comment(lib, "vfw32.lib")
//BITMAPINFOHEADERを元にAVIストリームのフォーマットを確定する
PAVISTREAM CreateDIBStream(PAVIFILE pAVIFile, LPBITMAPINFOHEADER pbih)
{
PAVISTREAM pAVIStream = NULL;
AVISTREAMINFO asf = {0};
asf.fccType = streamtypeVIDEO;
asf.fccHandler = mmioFOURCC('D', 'I', 'B', ' ');
asf.dwQuality = static_cast<DWORD>(-1);
asf.dwScale = 1;
asf.dwRate = 30;
asf.dwLength = 30;
//描写エリアの設定
::SetRect(&asf.rcFrame, 0, 0, pbih->biWidth, pbih->biHeight);
//AVIストリームの作成
HRESULT hResult = ::AVIFileCreateStream(pAVIFile, &pAVIStream, &asf);
//AVIストリームにBITMAPINFOHEADERを渡してフォーマットを確定する
hResult = ::AVIStreamSetFormat(pAVIStream, 0, pbih, sizeof(*pbih));
return pAVIStream;
}
//DIBイメージを作成する
HBITMAP CreateTestDIB(int width, int height)
{
BITMAPINFOHEADER bmih = {sizeof(bmih)};
bmih.biBitCount = 24;
bmih.biPlanes = 1;
bmih.biWidth = width;
bmih.biHeight = height;
BITMAPINFO bmi = {0};
bmi.bmiHeader = bmih;
LPVOID pvBits = NULL;
return ::CreateDIBSection(NULL, &bmi, DIB_RGB_COLORS, &pvBits, NULL, 0);
}
//お試し
int main()
{
PAVIFILE pAVIFile= NULL;
//AVIライブラリの初期化
::AVIFileInit();
//AVIファイルを開く
::AVIFileOpen(&pAVIFile, "test.avi", OF_CREATE | OF_READWRITE | OF_SHARE_EXCLUSIVE, NULL);
//DIBの作成
HBITMAP hBitmap = ::CreateTestDIB(120, 80);
//作成したDIBから情報を取る
DIBSECTION dib;
::GetObject(hBitmap, sizeof(dib), &dib);
//BITMAPINFOHEADERを元にAVIストリームを作成する
PAVISTREAM pAVIStream = ::CreateDIBStream(pAVIFile, &dib.dsBmih);
//AVIストリーム情報を取る
AVISTREAMINFO asi = {0};
::AVIStreamInfo(pAVIStream, &asi, sizeof(asi));
//DIBの背景色等を初期化しておく
HDC hDC = ::CreateCompatibleDC(NULL);
::SetTextColor(hDC, RGB(255, 255, 0));
::SetBkMode(hDC, TRANSPARENT);
::SelectObject(hDC, hBitmap);
for(int frame = 0; frame < asi.dwRate; ++frame)
{
RECT rc = {0, 0, dib.dsBm.bmWidth, dib.dsBm.bmHeight};
//取り敢えず[赤色]を変色させながら背景を塗り潰して見る
HBRUSH hBrush = ::CreateSolidBrush(RGB((256 / asi.dwRate) * frame, 0, 0));
::FillRect(hDC, &rc, hBrush);
::DeleteObject(hBrush);
//フレーム数をテキストで書き込んでみる
TCHAR text[80];
::wsprintf(text, "%d", frame);
::DrawText(hDC, text, ::strlen(text), &rc, DT_CENTER);
//AVIストリームの長さを取る
LONG lLen = ::AVIStreamLength(pAVIStream);
//AVIストリームにDIBイメージを書き込む
HRESULT hResult = ::AVIStreamWrite(pAVIStream, lLen, 1, dib.dsBm.bmBits, dib.dsBmih.biSizeImage, AVIIF_KEYFRAME, NULL, NULL);
}
//フレーム用に使ったリソースを捨てる
::DeleteDC(hDC);
::DeleteObject(hBitmap);
//AVIストリームを閉じる
::AVIStreamRelease(pAVIStream);
//AVIファイルを閉じる
::AVIFileRelease(pAVIFile);
//AVIライブラリの開放
::AVIFileExit();
return 0;
}
回答ありがとうございます。
教えていただいたサイトは私も参考にしていました。
前の回答者様のところにも書かしていただきましたが1コマづつBMPを登録することはできています。
複数コマを一度に登録しようとするとエラーになってしまします。
複数コマのBMPを一度に登録する例などがありましたら教えていただけないでしょうか?
No.2
- 回答日時:
追記。
良いサンプルがありました。下記ページのTEST03.Cを見て下さい。
http://www.ecoop.net/coop/vfw/avi.html
AVISTREAMINFO構造体の総コマ数を「LENG」に初期化してから「for (i=0;i<LENG;i++) 」のループで、LENG回、1コマづつAVIStreamWrite()で書き込んでいます。
この回答への補足
回答に書き忘れたのですが総コマ数は決まっていない(リアルタイムで作成されるBMPをその場でAVIに登録しています)のでAVISTREAMINFO構造体のdwLengthメンバは初期値として0を設定してあります。(1コマづつ登録する場合はこの設定で問題なく動作しています)
これは問題ないでしょうか?
回答ありがとうございます
教えていただいたサイトは私も参考にしていました。
1コマづつAVIStreamWrite()でBMPを書き込んでいくのはできています。
複数コマを一度にAVIStreamWrite()で書き込もうとすると戻り値が0x80044065(AVIERR_UNSUPPORTED?)となりエラーとなってしまいます。
ここでわからないのがlpBufferとcbBufferの指定なのですがlpBufferは1つの領域に複数のBMPデータをlSamplesの分だけ設定してcbBufferにはその領域のサイズを指定すればよいのでしょうか?
例:640×320 24bitのBMPの場合(BMPを一度に2つ書く場合)
BYTE byBuffer[640 * 320 * 3 * 2];
byBufferにBMPデータを設定(2枚分のBMPデータを続けて設定)
AVIStreamWrite(pAviStream,nStart,2,byBuffer,sizeof(byBuffer),AVIIF_KEYFRAME, NULL, NULL);
現在、上記のように設定しようとするとエラーになってしまいます。
間違っている点を教えていただけないでしょうか?
No.1
- 回答日時:
AVIFileCreateStream()を呼び出す際の、AVISTREAMINFO構造体のdwLengthメンバに「書き込むサンプル数の総数」をセットしなければいけません。
その上で、AVIStreamWrite()のlSamples引数に「1回で書き込むサンプル数」を指定します。
AVIStreamWrite()のlSamples引数が1でないのなら、データは「指定したサンプル数の分だけ、連続して並んでいる」のが想定されます。
AVIStreamWrite()のlSamples引数が1なら、データは「1サンプル分だけしかない」のが想定されます。
1分間の動画を作る場合、もし仮にフレームレート(1秒間のコマ数)が30コマなら、1分間の動画には1800コマ必要ですから、以下のようにします。
1.AVIFileCreateStream()を呼び出す際に、AVISTREAMINFO構造体のdwLengthメンバに1800をセットして呼ぶ
2.1コマ分のデータを用意する
3.AVIStreamWrite()のlSamples引数に1を指定して、1コマ書き込む
4.上記の2と3を1800回繰り返す
と言う処理が必要です。
「総サンプル数が1800」であれば良いので「10コマ書き込むのを180回繰り返し」でも構いませんし「100コマ書き込むのを18回繰り返し」でも構いません。
お探しのQ&Aが見つからない時は、教えて!gooで質問しましょう!
似たような質問が見つかりました
- その他(プログラミング・Web制作) pythonでクラスで複数のメソッドを利用する方法 2 2022/04/15 04:17
- Excel(エクセル) EXCELマクロでandroidタブレットから取りんだJPEGファイルをうまくセルに貼り付けられない 2 2022/07/31 15:03
- XML エクセルのマクロについて教えてください。 3 2023/02/06 09:06
- Excel(エクセル) エクセルのマクロについて教えてください。 2 2023/02/21 13:29
- その他(プログラミング・Web制作) python OpenPyXLを使って出力結果をエクセルに書き込み 2 2022/06/04 19:46
- C言語・C++・C# C# で、あるフォルダー内にあるすべてのテキストファイルを別のフォルダーにコピーする。 4 2022/11/21 13:23
- Visual Basic(VBA) 複数ファイルのデータの統合について 12 2022/05/14 12:03
- その他(IT・Webサービス) ホームページにカウント数を表示する 2 2022/10/28 10:37
- Visual Basic(VBA) エクセルのマクロについて教えてください。 1 2023/02/21 11:19
- Visual Basic(VBA) Excelのマクロについて教えてください。 作業フォルダ内に2つのファイルがあります。 このファイル 2 2023/07/09 13:40
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一番好きなみそ汁の具材は?
- ・泣きながら食べたご飯の思い出
- ・「これはヤバかったな」という遅刻エピソード
- ・初めて自分の家と他人の家が違う、と意識した時
- ・いちばん失敗した人決定戦
- ・思い出すきっかけは 音楽?におい?景色?
- ・あなたなりのストレス発散方法を教えてください!
- ・もし10億円当たったら何に使いますか?
- ・何回やってもうまくいかないことは?
- ・今年はじめたいことは?
- ・あなたの人生で一番ピンチに陥った瞬間は?
- ・初めて見た映画を教えてください!
- ・今の日本に期待することはなんですか?
- ・集中するためにやっていること
- ・テレビやラジオに出たことがある人、いますか?
- ・【お題】斜め上を行くスキー場にありがちなこと
- ・人生でいちばんスベッた瞬間
- ・コーピングについて教えてください
- ・あなたの「プチ贅沢」はなんですか?
- ・コンビニでおにぎりを買うときのスタメンはどの具?
- ・おすすめの美術館・博物館、教えてください!
- ・【お題】大変な警告
- ・洋服何着持ってますか?
- ・みんなの【マイ・ベスト積読2024】を教えてください。
- ・「これいらなくない?」という慣習、教えてください
- ・今から楽しみな予定はありますか?
- ・AIツールの活用方法を教えて
- ・最強の防寒、あったか術を教えてください!
- ・歳とったな〜〜と思ったことは?
- ・モテ期を経験した方いらっしゃいますか?
- ・好きな人を振り向かせるためにしたこと
- ・スマホに会話を聞かれているな!?と思ったことありますか?
- ・それもChatGPT!?と驚いた使用方法を教えてください
- ・見学に行くとしたら【天国】と【地獄】どっち?
- ・これまでで一番「情けなかったとき」はいつですか?
- ・この人頭いいなと思ったエピソード
- ・あなたの「必」の書き順を教えてください
- ・14歳の自分に衝撃の事実を告げてください
- ・人生最悪の忘れ物
- ・あなたの習慣について教えてください!!
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Eclipseで検索ができなくなった
-
0バイトのテキストファイル
-
【Excel VBA】取り込んだファイ...
-
C#について質問【複数の.datフ...
-
【VBA】複数CSVの特定範囲を1つ...
-
ファイル作成日時と更新日時を...
-
ディレクトリのサイズの取得
-
EXCELで複数のファイルを同じブ...
-
VB6.0のメモリリークについて
-
C++.NET 2003 「空のドキュメ...
-
HTMLまたはJavaScriptでフ...
-
CSVファイルの時刻の形式について
-
accessでクエリをExcelにエクス...
-
“ファイルに出力”した印刷ファ...
-
ATTファイルってどうやって開け...
-
Acrobat参照設定
-
COBOL、項目末尾に空白がある場...
-
accessのリポートを、excelに出...
-
VB(VBA)で、バイナリデータを使...
-
WORDのVBAで差し込み印刷時、デ...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Eclipseで検索ができなくなった
-
【Excel VBA】取り込んだファイ...
-
0バイトのテキストファイル
-
VBAで、JPG写真の撮影日時を読...
-
main関数のコマンドライン引数...
-
HTMLテキストリンクでExcelファ...
-
ファイル作成日時と更新日時を...
-
サイトマップにサブドメインを...
-
C++.NET 2003 「空のドキュメ...
-
C++によるファイル送受信プログ...
-
ファイル内容を比較する方法
-
File.Create で作成に失敗した場合
-
JavaでPDFファイルに変換するに...
-
VBS ファイルマージ処理
-
【VBA】印刷マクロのループ処理...
-
VB2008 iniファイルの全セクシ...
-
2GB以上のファイルを扱う方法
-
RPGでメッセージファイル利用
-
ディレクトリのサイズの取得
-
ファイルの排他について
おすすめ情報