4

24ビットのビットマップ画像をグレースケールに変換しようとしています。

#include<iostream>
#include<fstream>
#include<conio.h>
#include<stdio.h>
using namespace std;
class pixel{
            public:
                   unsigned char b;
                   unsigned char g;
                   unsigned char r;
            void display()
            {
                 cout<<r<<" "<<g<<" "<<b<<" ";
                 }
      }p1;
using namespace std;
int main(){
    unsigned char avg;
    fstream file("image.bmp",ios::binary|ios::in|ios::out);

    int start;
    file.seekg(10);
    file.read((char*)&start,4);


    file.seekg(start);
    int i=0;
   while(!file.eof()){
                      cout<<file.tellg();//Remove this and the program doesn't work!
                     file.read((char*)&p1,3);
                     avg=(p1.b+p1.g+p1.r)/3;
                     p1.b=avg;
                     p1.g=avg;
                     p1.r=avg;
                     file.seekg(-3,ios::cur);
                     file.write((char*)&p1,3);
                       }
    file.close();
    getch();
    return 0;
}

cout tellgステートメントを削除すると、ループは2回だけ実行されます。

coutステートメントを削除するとどのような違いが生じるのかわかりませんか?

結果:1ピクセルのみがグレースケールに変更されます。

私はここで私の問題のより単純なバージョンを見つけました

ファイルの読み取りと書き込みを同時に行いますか?

しかし、解決策が見つかりませんでした...

4

1 に答える 1

6

読み書きするときstd::fstreamは、読み書きを切り替えるときにシークが必要です。これは、ファイル ストリームが共通の入力位置と出力位置を共有するためです。効率的なバッファリングもサポートするには、現在の位置についてそれぞれの他のバッファに通知する必要があります。これは、シークが行うことの一部です。tellg()現在の位置にシークします。

特に実装が十分に最適化されている場合は、読み取りと書き込みを切り替えるのは非常に非効率的であることに注意してください。別のファイルを作成するか、適切なサイズのグループで値を更新する方がはるかに良いでしょう。

于 2012-09-22T17:48:32.087 に答える