• 締切済み

AVIStreamWriteの使用方法

BMPファイルからAVIファイルを作成する際のAVIStreamWriteの使用方法を教えてください。 AVIStreamWriteを使用して1枚ずつBMPファイルをAVIファイルに書き込むことはできたのですが複数のBMPファイルを一度にAVIファイルに書き込むことはできるのでしょうか。 AVIStreamWriteのパラメータに「書き込むサンプル数」の指定など複数ファイルの登録ができそうな感じがあるのですがうまくいきません。 おそらくパラメータの指定方法が誤っているのだと思うのですが、具体的な例などがありましたら教えてください。

みんなの回答

回答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; }

MOYAJI
質問者

お礼

回答ありがとうございます。 教えていただいたサイトは私も参考にしていました。 前の回答者様のところにも書かしていただきましたが1コマづつBMPを登録することはできています。 複数コマを一度に登録しようとするとエラーになってしまします。 複数コマのBMPを一度に登録する例などがありましたら教えていただけないでしょうか?

  • chie65535
  • ベストアンサー率43% (8512/19351)
回答No.2

追記。 良いサンプルがありました。下記ページのTEST03.Cを見て下さい。 http://www.ecoop.net/coop/vfw/avi.html AVISTREAMINFO構造体の総コマ数を「LENG」に初期化してから「for (i=0;i<LENG;i++) 」のループで、LENG回、1コマづつAVIStreamWrite()で書き込んでいます。

MOYAJI
質問者

お礼

回答ありがとうございます 教えていただいたサイトは私も参考にしていました。 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); 現在、上記のように設定しようとするとエラーになってしまいます。 間違っている点を教えていただけないでしょうか?

MOYAJI
質問者

補足

回答に書き忘れたのですが総コマ数は決まっていない(リアルタイムで作成されるBMPをその場でAVIに登録しています)のでAVISTREAMINFO構造体のdwLengthメンバは初期値として0を設定してあります。(1コマづつ登録する場合はこの設定で問題なく動作しています) これは問題ないでしょうか?

  • chie65535
  • ベストアンサー率43% (8512/19351)
回答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

  • コマンドプロンプトを使ったファイルコピーの方法

    コマンドプロンプトを使ったファイルコピーの方法 みなさんよろしくお願いします。 現在コマンドプロンプトを使用して、ファイルコピーを行おうとしています。 条件は以下の通りです↓ (1)元のファイルは1つ(例:0.bmp) (2)名前を連番にして、任意の複数ファイル作る。(0.bmp,1.bmp,2,bmp・・・) このようなファイル作成コマンドをご存じの方、ご指導ください!! よろしくお願いします。

  • Excel2003でBMPを整列・配置

    Excel2003に、BMPを挿入または貼り付けし、m列×n行に 整列・配置したいと考えています。 例:30枚のBMPファイルを3列×10行に配置する 今は、「複数オブジェクトの選択」「左右に整列」 「上下に整列」「上揃え」「左揃え」等を使用して 手動で整列・配置しているのですが、これよりも手間のかからない 方法でBMPを整列させる方法を具体的に 教えていただけませんでしょうか。 (BMPを配置する行列数とBMPが保存されているフォルダを 指定すると自動的にBMPを配置してくれるようなものが最も理想です) VBA、他のソフトを使用する等、方法は問いません。 よろしくお願いいたします。

  • 自動的に図を貼り付ける方法

    自動的にBMPファイルを指定したWORDファイルに貼り付ける ことはプログラムを用いて可能でしょうか? 現在は、BMPファイルをペイントで開きワードにコピーペースト しています。しかし、数が多いため何か良い方法を探しています。 プログラムに関しては殆ど知識が無く、どのように調べればよいのか 分からなかったので此処で質問させてもらいました。 もし、参考になるサイトや方法がありましたら教えて下さい。 宜しくお願いします。

  • 複数のデジカメ動画を1つのファイルにする方法

    キャノンpowershotA40を使用して、15秒の動画を撮っております。ひとつづつファイルを指定してメディアプレーヤーで見るのが面倒で、複数の動画ファイルをひとつのファイルにして連続で見る方法がないものか探しております。 動画ファイルはaviの拡張子です。

  • 最適な解の決定方法について

    複数のサンプルがそれぞれ2つのパラメータを持っている場合に、 それら2つのパラメータ(異なる単位)に基づいて、最も良いサンプル を数学を用いて判断するにはどのような方法を用いれば良いのでしょうか。 例えば、旅行先の候補が幾つかある中で、時間とお金という 2つのパラメータから最適な場所を決定する。という様な問題かなと思います。 参考になるサイト等、教えて頂けたら幸いです。 宜しくお願いします。

  • 画像ファイル形式変更方法について

    ファイル形式のbmpをjpegに複数枚一度に、例えば100ファイル辺りですが?Adobe Photoshop Elements4.0とPoint Shop Pro 7を使用しています。よろしくお願いします。

  • VB.NETの画像の切り取りについて教えて

    Dim bmp1 As Bitmap Dim bmp2 As Bitmap となっていて、bmp1にファイルから読み込んだ画像を入れてあり bmp2に切り出し位置とサイズを指定して、bmp1の一部を入れたいのですが、 どのようにやれば良いでしょうか。 PictureBoxを使う方法はサンプルを見つけたのですが、 PictureBoxを使わずにやりたいのですが方法がありましたら ご教授頂けないでしょうか。宜しくお願い致します。 Frameworkは1.1です。

  • Accessで他のアプリケーションファイルを開く方法は?

    Access2000でshell関数を使用するなどして、他のアプリケーションを起動する方法はありますが、アプリケーションを指定せずファイルだけを指定して、関連付けされたアプリケーションで開く方法はないでしょうか? (例: c:\test\sample.jpgを指定すると、関連付けされたペイントブラシが起動してファイルが開かれる)

  • VBから参照できないCのDLLを使用する方法

    Cで作成されたDLLがあるのですが、VBから参照設定しても「指定されたファイルへの参照は登録できません。」と怒られます。 そのようなDLLをどうしてもVBから使用したい場合はどうすれば良いでしょうか? 直接は無理だとしても、間に何かをかましてできると思うのですが、良い方法があれば教えてください。 ちなみに VB6 です。 よろしくお願いします。

  • AVI Makerにて

    AVI Makerを使っているのですが、JPEG⇒BMP変換のときに新しく複製されたBMP画像がもとのJPEG画像のあったフォルダに作成されます。JPEG画像をいくつかのフォルダで管理していると、AVIファイルを作り終えた後にBMPを削除するのが大変なのですが、なにか良い方法はないでしょうか? それとも何か設定が間違っているのでしょうか? 詳しい方、経験者の方、よろしくお願いします。

専門家に質問してみよう