1

PPMファイルをC/C++で保存するのに助けが必要です。3つの基本的なカラーチャンネルからPPM画像を保存したいと思います。チャネルは、void *ポインター(pRed、pGreen、およびpBlue)として表されます。これらの値は固定されているため、変更できません。

voidポインタをどのように解釈するかを決定するもう1つの変数があります。この変数は次のとおりです。

bpp=1正しいタイプはunsignedchar*です。バッファ要素はunsignedchar型です

bpp=2正しい型はunsignedshort*です。バッファ要素はunsignedshort型です。

ここで、この3つのカラーチャネルからppmファイルを保存します。

bpp変数に関する宣言は次のとおりです。

//bpp=1:
unsigned char* dRed = (unsigned char*)pImg->pRed;
unsigned char* dGreen = (unsigned char*)pImg->pGreen;
unsigned char* dBlue = (unsigned char*)pImg->pBlue;
unsigned char* dBw = (unsigned char*)pImg->pBw;

//bpp=2:
unsigned short* dRed = (unsigned short*)pImg->pRed;
unsigned short* dGreen = (unsigned short*)pImg->pGreen;
unsigned short* dBlue = (unsigned short*)pImg->pBlue;
unsigned short* dBw = (unsigned short*)pImg->pBw;

ppmファイルを書くための私のコード:

ofstream output(fname, ios::binary|ios::out);

output << "P3"<< endl <<"# foreground "<<endl;
output << itoa(width, fname, 10);
output << " ";
output << itoa(height, fname, 10);
output << endl;
output << itoa(255, fname, 10) << endl;
...     
for(int i=0; i<(height*width); i++){
  if(bytesPerP==1){
    output << (unsigned char)((char*)dRed) << " ";
    output << (unsigned char)((char*)dGreen) << " ";
    output << (unsigned char)((char*)dBlue) << " ";
    dRed = dRed + (i * bytesPerP);
    dGreen = dGreen + (i * bytesPerP);
    dBlue = dBlue + (i * bytesPerP);
}else if(bytesPerP==2){
    output << ((unsigned short)((char*)dRed))%256 << " ";
    output << (unsigned short)((char*)dGreen)%256 << " ";
    output << (unsigned short)((char*)dBlue)%256 << " ";

    dRed = dRed + (i * bytesPerP);
    dGreen = dGreen + (i * bytesPerP);
    dBlue = dBlue + (i * bytesPerP);
}

記録された画像の正しい「構造」が得られたので、ここにエラーがありますが、色は完全に奇妙です(サイコデリックスタイル):)インターネットで検索して多くのことをテストしましたが、どれも機能しませんでした。誰かが私を正しい方向に向けることができますか?

4

1 に答える 1

1

問題は、画像バッファからバイトを出力する方法です。実際のポインタ値自体を出力するのではなく、実際のデータ情報を取得するためにポインタを逆参照する必要があります。

たとえば、これは次のとおりです。

output << (unsigned char)((char*)dRed) << " ";

dRedにキャストされた4バイトまたは8バイトのポインタ値を出力しますunsigned char...ポインタdRed指している値が必要です。これは次のように実行されます。

output << *dRed << " ";

次に、各カラーチャネルのデータが個別の連続線形配列に格納されている場合(つまり、赤は赤ピクセルのみを指し、緑は緑ピクセルのみを指し、バッファは赤ピクセル、次に緑を指します) -ピクセル、次に青ピクセル)、チャネルあたり16ビットの場合、値が正しくインクリメントされていません。バッファが線形配列の場合は、次のようにするだけです。

 output << " " << dRed[i] << " " << dGreen[i] << " " << dBlue[i] << endl;

ここで、余分な空白は、ピクセル値のサンプルを空白文字で囲む必要があるPPM標準に準拠する必要があります。

最後に、出力する「プレーン」PPM形式では、行が70文字を超えてはなりません...間違いなくその制限を超えています...

于 2012-02-14T18:43:59.330 に答える