画像の処理

[戻る]
cc 2009/12/11(金) 10:57:58
いつもお世話になっています、ccです。

質問:
2色の画像(TIFF形式)をグレに変換したいのですが、
どうすればいいでしょうか。
(CImageクラスを使って、画像を表示できています)

よろしくお願いします。

環境:.Net2002 XP

επιστημη [E-Mail] [HomePage] 2009/12/11(金) 11:08:24
"グレ"てなんですか?

cc 2009/12/11(金) 11:15:05
すみません。

//グレ
グレーに訂正します。
グレー色に変換したい。

よろしくお願いします。

PATIO 2009/12/11(金) 13:30:15
もしかしてグレースケールと言う意味でしょうか?
淡色で書いちゃうと単なる白黒二値の黒の所が灰色になるだけに
なっちゃうと思いますけれど。

何とか自分がイメージしている処理の内容をうまく伝えるように
説明しないと文字だけでやり取りしているので誤解されたまま
話が進んでしまいます。
一般的な用語を知っているのであれば、そっちで説明するのが
簡単なんですが、用語が分からない時はイメージが伝わるように
説明する努力が必要になりますよ。

cc 2009/12/11(金) 15:12:51
PATIOさん
ご回答ありがとう。

>淡色で書いちゃうと単なる白黒二値の黒の所が灰色になるだけに
白黒二値の黒の所が灰色に変換したい。
スライダーコントロールのスライダー値によって濃淡を調整したい。

>...説明する努力が必要になりますよ
頑張ります。

よろしくお願いします。

επιστημη [E-Mail] [HomePage] 2009/12/11(金) 15:47:01
...で、何がわからんのですか?

CImageには GetPixel/SetPixelメソッドがあるんだから

for ( x : 幅 )
  for ( y : 高さ ) 
    image.SetPixel(x, y, 変換関数(GetPixel(x,y)));

んでもって変換関数をテキトーに定義するだけちゃいますの?

cc 2009/12/14(月) 09:05:50
επιστημηさん
ご回答ありがとう。

以下のようにやってみたのですが

COLORREF color;
color = RGB(198,198,198);
 for (int j=0; j<250; j++)
  for (int i=0; i<250; i++) 
       pDoc->imgOriginal1.SetPixel(j, i, color);

pDoc->imgOriginal1.StretchBlt(*pDC, ・・・)
    
色が変わりませんでした。
何か間違っているのでしょうか。

よろしくお願いします。

επιστημη [E-Mail] [HomePage] 2009/12/14(月) 09:27:29
GetPixelして 198,198,198 になってるならば色の変更はできてるわけで、
そいつを画面に出すとこでしくってんでしょね。

subaru 2009/12/14(月) 09:43:44
CImageのオブジェクトがフルカラーの場合はSetPixelで色を変えられます。
パレットを持つ場合はこちら
http://msdn.microsoft.com/ja-jp/library/6kt6bh7e%28VS.80%29.aspx

#なぜかスパムキーワードになるのでリンク。

cc 2009/12/14(月) 09:58:49
επιστημηさん
ご回答ありがとう。

>GetPixelして 198,198,198 になってるならば色の変更はできてるわけで、
帰ってきたRGBの値は(255,255,255)でした。
うまく変更できっていないですね。
使ってファイルの形式がTIFFでした。
(2色と256色です)

よろしくお願いします。

cc 2009/12/14(月) 11:40:15
subaruさん
ご回答ありがとう。
フルカラーをやってみたら、正常に色が変わりました。

cc 2009/12/14(月) 11:47:45
subaruさん
ご回答ありがとう

引数の部分がどう設定すればいいでしょうか。
よろしくお願いします。

cc 2009/12/14(月) 11:48:31
subaruさん
ご回答ありがとう

スパムチェックエラー
送信できません

cc 2009/12/14(月) 11:53:05
subaruさん
ご回答ありがとう

引数の部分がどう設定すればいいでしょうか。
よろしくお願いします。

cc 2009/12/14(月) 11:55:15
pDoc->imgOriginal11.(?,color,?)

subaru 2009/12/14(月) 12:46:23
1bitの場合はこんな感じかな。

RGBQUAD rgb[2] = {{198,198,198,0},{255,255,255,0}};
image.SetColorTable(0, 2, rgb);

cc 2009/12/14(月) 13:52:31
subaruさん
ご回答ありがとう

>RGBQUAD rgb[2] = {{198,198,198,0},{255,255,255,0}};
>image.SetColorTable(0, 2, rgb);
正常に表示できました。
ありがとう。

以下の質問があります。
1.
RGBQUAD rgb[2] = {{198,198,198,0},{255,255,255,0}};
pDoc->imgOriginal1.SetColorTable(0, 2, rgb);
全領域(Image)に変換された、
部分的に変換したい場合可能なのでしょうか。
例
for (int j=0; j<250; j++){
     for (int i=0; i<250; i++){ 
      ・・・
    }
}

cc 2009/12/14(月) 14:03:56
つづき
2、
pDoc->imgOriginal1.SetPixel(j, i, color);
あるいは、
pDoc->imgOriginal1.SetColorTable(0, 2, rgb);
はOnDraw()内ありますが、
表示スピードが遅くなっています。

やりたいことは、
Imageファイルを読み込み時に一回変換して、
システムを終了するまで使えます、
(必要の場合はもう一回変換して、)
そうならば、表示のスピードが早くなりますね。
問題というのは、一回変換したファイルがどう保存する問題が出ってきます、
どう解決すれば良いでしょうか。

よろしくお願いします。

subaru 2009/12/14(月) 14:45:06
>全領域(Image)に変換された、
>部分的に変換したい場合可能なのでしょうか。
SetPixelを使うかGetBitsで直接アクセスして
任意の範囲を任意の色に変更します。
(モノクロのままだと当然2色しか使えません)

>はOnDraw()内ありますが、
>表示スピードが遅くなっています。
CImageをローカル変数で使ってるんでしょうか?
クラスメンバに保持しておけば毎回変換せずに済みます。

cc 2009/12/18(金) 14:45:04
subaruさん
返事が遅くなりました。すみませんでした。

できたこと
>CImageをローカル変数で使ってるんでしょうか?
>クラスメンバに保持しておけば毎回変換せずに済みます。
うまくできました。

できていない。
8bitの場合はどうやれば良いでしょうか。

質問1
フルカラーの場合は
for (int j=0; j<ScrWH->x; j++){
 for (int i=0; i<ScrWH->y; i++){ 
   imgOriginal1.SetPixel(j, i, color);
 }
}
変換処理の時間がかかります。もっと早く処理の方法があるのでしょうか。
        
質問2
変換処理後のファイルを保存したい場合は、どう保存すればいいでしょうか。
(特にフルカラーファイルの保存)

よろしくお願いします。

subaru 2009/12/19(土) 11:38:40
>質問1
>フルカラーの場合は
>for (int j=0; j<ScrWH->x; j++){
> for (int i=0; i<ScrWH->y; i++){ 
>   imgOriginal1.SetPixel(j, i, color);
> }
>}
>変換処理の時間がかかります。もっと早く処理の方法があるのでしょうか。

GetBits+GetPitchかGetPixelAddressを使う方がはるかに高速です。
例えばCImageが32bitの場合に(10, 10)-(20, 20)の範囲のみを
RGB(198,198,198)にするなら次のように書くことができます。

for(int y = 10; y < 20; y++) {
    DWORD* ppixels = static_cast<DWORD*>(image.GetPixelAddress(0, y));
    for(int x = 10; x < 20; x++) {
        ppixels[x] = 0xffc6c6c6;
    }
}

この場合各ピクセルは4バイトでARGBを表しています。
8bitで行う場合には各ピクセルは1バイトになりますが、
パレットへのインデックスを入れてやらないといけないので、直接色を指定したい場合は
CPalette::GetNearestPaletteIndexも使うとよいかもしれません。

>質問2
>変換処理後のファイルを保存したい場合は、どう保存すればいいでしょうか。
>(特にフルカラーファイルの保存)

具体的にどの部分がわかりませんか?
まずはCImage::Saveメソッドの仕様をご確認ください。

cc 2009/12/28(月) 15:18:50
subaruさん
返事が遅くなりました。すみませんでした。
(最近、別の仕事をしています)

>for(int y = 10; y < 20; y++) {
>    DWORD* ppixels = static_cast<DWORD*>(image.GetPixelAddress(0, y));
>    for(int x = 10; x < 20; x++) {
>        ppixels[x] = 0xffc6c6c6;
>    }
>}
以上のようにやってみたら、うまくできませんでした。
色が変えたのですが、直線のグレ、緑、ピンクなどが並んでいます。元の図画が変えました。
どうすれば良いでしょうか。

>まずはCImage::Saveメソッドの仕様をご確認ください。
できました。ありがとうございました。

よろしくお願いします。

subaru 2009/12/28(月) 17:02:48
>>for(int y = 10; y < 20; y++) {
>>    DWORD* ppixels = static_cast<DWORD*>(image.GetPixelAddress(0, y));
>>    for(int x = 10; x < 20; x++) {
>>        ppixels[x] = 0xffc6c6c6;
>>    }
>>}
>以上のようにやってみたら、うまくできませんでした。
>色が変えたのですが、直線のグレ、緑、ピンクなどが並んでいます。元の図画が変えま
した。
>どうすれば良いでしょうか。

このコードは32ビットを前提にしてますけど
画像を読み込んだ後に32ビットに変換してますかね?
SetPixelのようにフォーマットを意識しないで使えるものではありません。

PATIO 2009/12/28(月) 17:16:14
しばらく静観していましたが、
イメージ用のAPIとかクラスの関数等を使用せずに
画素情報を自分でハンドリングするのでしたら
画像情報がメモリ上でどのように格納されているのか
という部分の知識が必須になりますよ。

その部分の知識が足りないのであれば、
その部分に関してはWeb上で情報を検索するなり、
書籍で勉強するなりしてそれなりの知識を収集しないと
掲示板上の質問だけで何とかするのはちょっと無理だと思います。
ただうまく行きませんでは知識が身に付きませんから
その辺はある程度自力で調べて勉強した方が良いと思いますよ。

szgy_phys [HomePage] 2010/01/07(木) 22:19:28
PATIOさんに同感です
メモリー上での格納方法(DIB形式での)を理解することが先決だと思います

cc 2010/01/20(水) 08:45:35
subaruさん、PATIO さん、szgy_physさん
ご返事ありがとう。

>このコードは32ビットを前提にしてますけど
>画像を読み込んだ後に32ビットに変換してますかね?

すみませんが、24ビットです。(フルカラー)

>SetPixelのようにフォーマットを意識しないで使えるものではありません。

>その辺はある程度自力で調べて勉強した方が良いと思いますよ。

そうですね、その辺が確かに知識が不足ですが、
時間があれば勉強します。

いろいろ教えていただき、ありがとうございました。

subaru 2010/01/22(金) 13:32:22
24ビットで処理する場合は各ピクセルは3バイトになります。

for(int y = 10; y < 20; y++) {
    RGBTRIPLE* ppixels = static_cast<RGBTRIPLE*>(image.GetPixelAddress(0, y));
    for(int x = 10; x < 20; x++) {
        RGBTRIPLE& rgb = ppixels[x];
        rgb.rgbtBlue = rgb.rgbtGreen = rgb.rgbtRed = 0xc6;
    }
}

古いスレッドには追加発言できません。