• ベストアンサー

画像変換の高速化

DOS/VマシンでMicrosoft C Ver6.0でCの勉強をしています。 初心者の入り口レベルなので、質問の内容が拙いかもしれませんが、よろしくお願いします。 BMPの8ビット形式の画像を任意のデータに変換するプログラムを作ったのですが、処理速度がとても遅く(1.7M位で5分30秒かかりました)何とか高速化をしたいと思います。 今やっているやり方はX方向分(ファイルサイズをYサイズで割ったもの)のバッファを取り、書込む時に実際のX方向分のみ書き込ませる。 をY方向分繰返すという処理です。 絶対もっと早くなる方法があるはずだと思うのですが、いくら考えても全く分かりません。 アドバイスをよろしくお願いします。

質問者が選んだベストアンサー

  • ベストアンサー
  • titokani
  • ベストアンサー率19% (341/1726)
回答No.6

>いえ、えーと書き方が悪かったようで、マイクロソフトC のVer6 です。 あ、なるほど、こちらでしたか。失礼しました。 でしたら16bit環境ですね。 16bit環境では、CreateFileMappingは使えないですね。 あと、メモリも最大で640KBですから、ファイルを全部メモリに読み込みのも無理です。 メモリをできるだけ確保して、数十ラインづつまとめて処理すれば、それなりに早くなるかもしれません。 あるいは実体がWindows98ということですから、32bit環境で動かすこともできるかもしれません。このほうが搭載されているメモリを有効に使えますね。

siriusu-1
質問者

お礼

お忙しい中、何度もご回答ありがとうございます >数十ラインづつまとめて処理すれば、それなりに早くなるかもしれません ファイルサイズによって、ライン数を変えるような作り方に変更してみます。 とても参考になりました。 もう一度BMPフォーマットを見直して、1ラインづつ読まなくても上手く処理できるように工夫してみます。 BMPは4バイトづつデータを取って行くので、最後のデータに0~3の余りが出てしまい、それの処理をするのに1ラインずつ読んでいました。 これからは一度にたくさんのラインを読んで処理したのち書き込むように考えてみます。

その他の回答 (6)

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.7

とりあえず、メモリを最大限確保したうえで、単なるファイルコピーを作ってみましょう。 それで早くなるようなら望みはあります。 早くならないようなら、別の方法を模索したほうがいいでしょう。

siriusu-1
質問者

お礼

ありがとうございました。 方向性が決まり現在今メモリの取り方について一から考え直す方向で考えております。 色々アドバイスを頂きありがとうございました。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.5

>で書き込みメディアがCFです CF上で作業していたら、そんなスピードかもしれません。 試しに、CF上でファイルのコピーを行うとどのくらいかかるでしょうか? もし、ファイルをコピーするだけでも5分程度かかるのであれば、なにをどう頑張ってもそれ以上早い処理は不可能です。 以後は余談なのですが、 >今はPC Dosの環境で作業しております。 PC Dosというと、16ビット環境になります。 VC++6で16ビット環境の開発はできませんから、どちらかに勘違いがあると思います。 普通、Windows2000とかXPとかで使われる、DOSのような画面は、「コマンドプロンプト」と呼びます。 でも、 >CPUインテルPentium3(クロックはちょっと分かりません) ということから、本当にPC-DOSである可能性も捨てきれず・・。 PC-DOSでVC++6.0は動かないから、クロス開発? でも、PC-DOSにCFのドライバなんてあったかな??

siriusu-1
質問者

補足

お返事ありがとうございます。 >PC-DOSでVC++6.0は動かないから、クロス開発? いえ、えーと書き方が悪かったようで、マイクロソフトC のVer6 です。 >でも、PC-DOSにCFのドライバなんてあったかな?? よく分からないのですが、Windows98のPCを改造してPC-DOSマシンにしてあるらしく、CFが使えるようになっています。 Microsoft Visual C++ 2005の環境もあります。(ただ、全く勉強をしていないので使えないのですが) >試しに、CF上でファイルのコピーを行うとどのくらいかかるでしょうか? 同じものをコピーして5秒程でした。 かなり凹んでます。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.4

私も #3 と同じく「1.7MB の読み書き」に 5分もかかるとは思えないです. ハードディスクだとしたらあまりにも遅すぎ. そんな状況だと, CreateFileMapping (Unix なら mmap) を使っても「劇的に」速くなることはないような気がします. この辺はファイルアクセスの際のバッファリングに関係するんだけど, fread でデータを読み込むと最悪 1.OS のバッファ 2.C のライブラリのバッファ 3.ユーザが確保したバッファ の 3つのバッファをデータが通る可能性があります. つまり, 2回もデータをコピーしないといけないわけです. ところが, CreateFileMapping なり mmap なりを使うと2と3をすっとばすことができます. だから速くなる (かもしれない) というわけ. でも, 今の場合は「そもそもディスク (?) からのアクセスが遅い」ような気がするので無意味かなぁ.... まあ, Windows や Unix など*特定の OS を想定しない*のなら, #1 で言われる通り「fread/fwrite のバッファを大きくとる」のが最初かな.

siriusu-1
質問者

お礼

丁寧なご回答ありがとうございます。 3つもバッファが有るんですね。初めて知りました。 そしてそれ全てを通る場合と通らない場合があると言うのもビックリしました。 自分のファイルアクセスがどのようになっているのか、全く分からない状況なのでハッキリした事は言えませんが、もしかするとCF(コンパクトフラッシュ)とのやり取りに問題があるのかもしれません。 出来ればハードに入れて試したいのですが・・・ハードが無い状態なので・・・・・・・・・(有り得ない状態なのですが本当に無いです) ※書いている自分も信じられなくて何度も何度も確認した位です(苦笑) この環境で作る事事態間違っていると思うのですが、CFで乗り気らなければならない状態です(ちなみにCFは256Mです) 一旦Dosでのプログラムは一時中止して、上司の指示を仰ぎます。 大変勉強になりました。ありがとうございます。

  • titokani
  • ベストアンサー率19% (341/1726)
回答No.3

>for(i=1; i <= y_size; i++) { >fread(callo_mem,x,1,BMP_fp); >fwrite(callo_mem,x_size,1,T_fp); >} >の分だけで5分かかっておりました。他の部分は30秒程度です。 いくらなんでも5分もかかるかな。x_size,y_sizeの値はいくらですか? あと、CPUクロック、メモリサイズ、メディア種類などもお願いします。

siriusu-1
質問者

補足

ご回答ありがとうございます。 CPUインテルPentium3(クロックはちょっと分かりません) メモリサイズは256 で書き込みメディアがCFです 今回使用した画像はx=2000でy=8400です 多分その逆だとかなり早くなるとは思います。 今はPC Dosの環境で作業しております。

  • Tacosan
  • ベストアンサー率23% (3656/15482)
回答No.2

まず最初にやるべきは「どこに時間がかかっているのか」を明らかにすることなんですが, それは OK なんですか? 例えば, 「実際の処理の時間に比べてファイルの読み書きが明らかにオーバヘッドになっている」とかいうことがわかっているんでしょうか? そこをごりごりやるなら #1 で言われる通り「読み書きの回数をなるべく減らす」ことでしょうね. Windows でいくという覚悟 (と十分なメモリ) があれば CreateFileMapping を使うとおそらく最速.

siriusu-1
質問者

お礼

ご回答ありがとうございます。 >「どこに時間がかかっているのか」 php504様の補足にも書かせて頂いた for(i=1; i <= y_size; i++) { fread(callo_mem,x,1,BMP_fp); fwrite(callo_mem,x_size,1,T_fp); } の分だけで5分かかっておりました。他の部分は30秒程度です。 30秒も長いので他の方法を模索するつもりですが、一番の原因である読み書きの部分を何とかしないとダメだと思います。 >「読み書きの回数をなるべく減らす」 読み書きどちらかが遅いというわけでなく、どちらも遅いという事なんですね。なのでどちらも回数を減らす方向で作り替えなければならない という事ですね。 >CreateFileMapping ちょっと知らない言葉ですが、Windowsならこれを使うと劇的に処理が速くなるのですね。 Windows版も視野に入れていますので調べてみます。 アドバイスありがとうございます。

  • php504
  • ベストアンサー率42% (926/2160)
回答No.1

実際のソースを見ないとわからないです ファイルの入出力を1ラインごとにやっているのなら遅くなる原因の一つにはなるでしょう メモリが十分なら画像を全部読み込み->変換処理->画像をまとめて書き込みにすればファイルの入出力の回数は1回ずつですみます。

siriusu-1
質問者

補足

素早いご回答ありがとうございます。 >ファイルの入出力を1ラインごとにやっているのなら遅くなる原因の一つにはなるでしょう やはりそうですか・・・。 今はXサイズを1ラインと考えて入出力を繰り返しております。 for(i=1; i <= y_size; i++) { fread(callo_mem,x,1,BMP_fp); fwrite(callo_mem,x_size,1,T_fp); } 画像のサイズがまちまちなのでその辺をどうしたらいいのか分からず悩んでおります。(40M以上の画像というものがあったので・・・) 処理速度を上げる場合、一気にバッファに貯めてから処理をするというのが早くなる方法ですか? 読みと書きどちらの方が遅くなるのですか? それともどちらも同じ位の処理時間なのでしょうか? すみません質問攻めで・・・。

関連するQ&A