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で質問しましょう!
関連するカテゴリからQ&Aを探す
おすすめ情報
- ・漫画をレンタルでお得に読める!
- ・一回も披露したことのない豆知識
- ・これ何て呼びますか
- ・チョコミントアイス
- ・初めて自分の家と他人の家が違う、と意識した時
- ・「これはヤバかったな」という遅刻エピソード
- ・これ何て呼びますか Part2
- ・許せない心理テスト
- ・この人頭いいなと思ったエピソード
- ・牛、豚、鶏、どれか一つ食べられなくなるとしたら?
- ・あなたの習慣について教えてください!!
- ・ハマっている「お菓子」を教えて!
- ・高校三年生の合唱祭で何を歌いましたか?
- ・【大喜利】【投稿~11/1】 存在しそうで存在しないモノマネ芸人の名前を教えてください
- ・好きなおでんの具材ドラフト会議しましょう
- ・餃子を食べるとき、何をつけますか?
- ・あなたの「必」の書き順を教えてください
- ・ギリギリ行けるお一人様のライン
- ・10代と話して驚いたこと
- ・家の中でのこだわりスペースはどこですか?
- ・つい集めてしまうものはなんですか?
- ・自分のセンスや笑いの好みに影響を受けた作品を教えて
- ・【お題】引っかけ問題(締め切り10月27日(日)23時)
- ・大人になっても苦手な食べ物、ありますか?
- ・14歳の自分に衝撃の事実を告げてください
- ・架空の映画のネタバレレビュー
- ・「お昼の放送」の思い出
- ・昨日見た夢を教えて下さい
- ・ちょっと先の未来クイズ第4問
- ・【大喜利】【投稿~10/21(月)】買ったばかりの自転車を分解してひと言
- ・メモのコツを教えてください!
- ・CDの保有枚数を教えてください
- ・ホテルを選ぶとき、これだけは譲れない条件TOP3は?
- ・家・車以外で、人生で一番奮発した買い物
- ・人生最悪の忘れ物
- ・【コナン30周年】嘘でしょ!?と思った○○周年を教えて【ハルヒ20周年】
- ・10秒目をつむったら…
- ・人生のプチ美学を教えてください!!
- ・あなたの習慣について教えてください!!
- ・都道府県穴埋めゲーム
デイリーランキングこのカテゴリの人気デイリーQ&Aランキング
-
Eclipseで検索ができなくなった
-
【Excel VBA】取り込んだファイ...
-
0バイトのテキストファイル
-
CreateFile関数を用いたファイ...
-
CSV名と同じシートを選択して取...
-
2GB以上のファイルを扱う方法
-
C#でtiffファイルのページ数を取得
-
Microoffice word 2007
-
アスキーコードまたはエスケー...
-
ファイルアップロードについて
-
CSVファイルの時刻の形式について
-
accessでクエリをExcelにエクス...
-
テキストファイルの一部分を抽...
-
テキストファイルをSQLServerデ...
-
テキストファイルの特定行の削...
-
既存のテキストファイルを開く方法
-
STM32 Nucleo-F446REでデータを...
-
フリーツール「PDF Image Extra...
-
Acrobat参照設定
-
COBOL、項目末尾に空白がある場...
マンスリーランキングこのカテゴリの人気マンスリーQ&Aランキング
-
Eclipseで検索ができなくなった
-
【Excel VBA】取り込んだファイ...
-
0バイトのテキストファイル
-
VBAで、JPG写真の撮影日時を読...
-
main関数のコマンドライン引数...
-
ディレクトリのサイズの取得
-
VB6.0のメモリリークについて
-
サイトマップにサブドメインを...
-
HTMLテキストリンクでExcelファ...
-
ファイル作成日時と更新日時を...
-
C++.NET 2003 「空のドキュメ...
-
JavaでPDFファイルに変換するに...
-
VB2008 iniファイルの全セクシ...
-
<input type="file" で初期値...
-
リンク先がjspファイルなのです...
-
【VBA】複数CSVの特定範囲を1つ...
-
msgget()で指定するkey値について
-
Javaのファイルダウンロードに...
-
BASP21のファイルアップロード...
-
vbaの構文の修正相談(xmlファ...
おすすめ情報