数値表示について

[戻る]
志摩 [E-Mail] 2003/02/11(火) 17:07:50
はじめまして。
VC++.netを始めたばかりの初心者です。
今、画像処理を行っていて、RGB値とHSV値を数字で表示できなくて困ってます。

color= (COLORREF)GetPixel(hdc,0+i,0+j);
r=GetRValue(color)/255.0;
g=GetGValue(color)/255.0;
b=GetBValue(color)/255.0;
RGBtoHSV(hdc,r,g,b,h,s,v);

wsprintf(str,"%5d %5d %5d",r,g,b);
TextOut(hdc,0,470,str,15);

このようにプログラムを作ったのですが、
数値が表示できません。
HSVにいたっては、”int型に変換できません”というエラーがでました。
どうしたらいいでしょうか??

RAPT 2003/02/11(火) 17:54:04
r, g, b の型は?

各変数の型を明示してください。

コンパイルは通っていますか?

コンパイル成功しているなら、どこまで正常に処理できているかを明示してください。
# 要デバッガ等による確認。

> wsprintf(str,"%5d %5d %5d",r,g,b);
r, g, b がもし、double型なら、%d ではなく、%lfを使用してください。

Windows98/VC++6.0sp5pro/SDK-may2002/ATL3.0/WTL7.0

wood 2003/02/11(火) 22:10:53
>RGBtoHSV
って何?
VC6.0の人には分からないことですかね?
RGBtoHSBはありましたけど
http://www.microsoft.com/japan/msdn/library/default.asp
ここでも検索してみたけど無かったよ!

>color= (COLORREF)GetPixel(hdc,0+i,0+j);
これなんでキャストしなきゃいけないの

MSDNは
-------------------------------------------------
COLORREF GetPixel(
  HDC hdc,    // デバイスコンテキストのハンドル
  int nXPos,  // ピクセルの x 座標
  int nYPos   // ピクセルの y 座標
);
-------------------------------------------------
こうなってたけど?

志摩 [E-Mail] 2003/02/12(水) 16:50:53
r,g,bは int型 です。
ソースを載せます。
   void ShowBMP(HDC hdc)
    {
        HDC         hmdc;
        HBITMAP     hBitmap;
    COLORREF    color;
        int         i,j,k,l,r,g,b,r1,g1,b1;
    int         size=100;
    char        str[5];

        hBitmap = LoadBitmap(hInst,"IDB_FAMILY");
        hmdc = CreateCompatibleDC(hdc);
        SelectObject(hmdc, hBitmap);
        BitBlt(hdc,0,0,290,415,hmdc,0,0,SRCCOPY);
        DeleteDC(hmdc);
        DeleteObject(hBitmap);
        
    for(j=0; j<size; j+=size)
      for(i=0; i<100; i+=size){
        r1=0;g1=0;b1=0;
        for(l=0; l<415; l++)
          for(k=0; k<size; k++){
            color= (COLORREF)GetPixel(hdc,0+i,0+j);
            r1+=GetRValue(color);
                         g1+=GetGValue(color);
                         b1+=GetBValue(color);
          }
         r=r1/(size*415);
                    g=g1/(size*415);
                    b=b1/(size*415);

                    for(l=0; l<415; l++)
          for(k=0; k<size; k++)
           SetPixel(hdc,300+i+k,0+j+l,RGB(r,g,b));
            }
            wsprintf(str,"%5d",r);
            TextOut(hdc,0,430,str,5);
    }

画像をモザイク化して、rgbの値を表示したいのですが、
デバッグすると、
Run-Time Check Failure #2 - Stack around the variable 'str' was corrupted.
というエラーがでます。

開発環境は windowsXP VC++.net win32アプリケーションです。

REE 2003/02/12(水) 17:28:00
他にも突っ込みたいところ盛り沢山ですがそれはさておき

>char        str[5];

>wsprintf(str,"%5d",r);

strの大きさが足りていません。

2003/02/12(水) 20:31:24
>Run-Time Check Failure #2 - Stack around the variable 'str' was corrupted.
>というエラーがでます。
の原因は REE さんが指摘なさっている通りですが、それが解決しても以下に述べる点が
解決できない以上不思議な動作をする事は変らないでしょう
(char str[6]; なら動作するかも知れませんが、私なら 12 バイト程度は確保します)

あなたのコードは for の入れ子関係がよく分かりませんでしたので、私なりに解釈して
入れ子関係を割り出してみましたが、間違いはありませんか?
    for(j=0; j<size; j+=size)  {
      for(i=0; i<100; i+=size) {
         r1=0;g1=0;b1=0;
         for(l=0; l<415; l++)  {
           for(k=0; k<size; k++) {
               color= (COLORREF)GetPixel(hdc,0+i,0+j);
               r1+=GetRValue(color);
              g1+=GetGValue(color);
              b1+=GetBValue(color);
           }
         }
         r=r1/(size*415);
         g=g1/(size*415);
         b=b1/(size*415);

         for(l=0; l<415; l++)  {
           for(k=0; k<size; k++)  {
             SetPixel(hdc,300+i+k,0+j+l,RGB(r,g,b));
           }
         }
      }
      wsprintf(str,"%5d",r);
      TextOut(hdc,0,430,str,5);
さて、上記のコード変換が正しかったとして話を進めます

i のループの内側に制御変数 l,k のループがありますが、GetPixel() は l.k に無関係
なコードですから、外に出して(0+ も不要なので取って)しまいます

    for(j=0; j<size; j+=size)  {            //// j のループ
      for(i=0; i<100; i+=size) {            //// i のループ(二つ目のループ)
         color= (COLORREF)GetPixel(hdc, i, j);
         r1=0; g1=0; b1=0;
         for(l=0; l<415; l++)  {            //// l のループ1
           for(k=0; k<size; k++) {          //// k のループ1
               r1+=GetRValue(color);
              g1+=GetGValue(color);
              b1+=GetBValue(color);
           }
         }
         r=r1/(size*415);
         g=g1/(size*415);
         b=b1/(size*415);

         for(l=0; l<415; l++)  {           //// l のループ2
           for(k=0; k<size; k++)  {        //// k のループ2
             SetPixel(hdc,300+i+k,0+j+l,RGB(r,g,b));
           }
         }
      }
      wsprintf(str,"%5d",r);
      TextOut(hdc,0,430,str,5);

これであなたのコードの正体が少し見えてきました。さて、初めの二つのループですが
int size =100; と定義しているので、このループは1度しか回れません。その結果あなたは
縦1ドット、横1ドット分の画像を制御変数 i,j で廻して、色を取り出している事になり
ます。その結果、l,k のループ1は何がしたいのか意味不明なことがはっきりして来ました。
この(意味が判らない)ことは l,k のループ2についても言えます。(謎がかえって深まる
だけですが、恐らくは元の画像の横に何か描きたかったのではないかと推測できなくはない
と感じていますが、それなら 415 は何処から出てきた値なのかが私には説明不可能です)

志摩 [E-Mail] 2003/02/13(木) 17:52:06
>strの大きさが足りていません。
簡単なプログラムにして、
strの大きさを変えたところ、
数値がでました。ありがとうございます。

が、意味不明の文字がでてしまいました。
R=179、G=117、B=2 のところ
R=5179、G=117、B=2¢フフフ(フフフは半角です)と出ました。
  ^                   ^^^^^^
なぜなんでしょう??

REE 2003/02/13(木) 20:11:41
そういう場合には、その変更したソースファイルを提示してください。

ソースファイルが不明なので推測になりますが、
考えられる原因としては、下記のようなものがあげられます。

1.wsprintfのフォーマット文字列が間違っている。
  %5d を 5%d と書いていませんか?
2.TextOutの第5引数が間違っている。(大きすぎる)
  数字を指定するのは止めて、strlen(str) としましょう。
3.strの幅がまだ足りない。

おそらく1と2が該当しているのではないでしょうか?

志摩 [E-Mail] 2003/02/20(木) 16:03:11
[[解決]]
無事問題は解決しました。
ご助言をくださった皆様
ありがとうございました。

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