none
GDI+のDrawLineでペン幅が異なる RRS feed

  • 質問

  • 始めまして。

    GDI+のDrawLineにて、同じペン幅で線を描画しているのですが、描く位置によりペン幅が異なるように見えます。
    同じペン幅を指定した場合、どの位置に書いても同じペン幅で描くようにするにはどうしたらよいかご存知ないでしょうか。

    VS2005 MFCシングルドキュメントプロジェクトを作成し、ViewのOnDrawにて下記コードを実行すると、
    私の環境では1dot幅の線と2dot幅の線が表示されます。
    たぶん内部でペン幅をdotに変換する箇所で計算結果が違うのでしょうが、それを同じにしたいのです。

    ぶしつけではありますが、宜しくお願いいたします。

    HogeView:SurprisenDraw(CDC* pDC)
    {
        // Graphics作成
        Gdiplus::Graphics g(pDC->GetSafeHdc());
        // 単位をmm系に
        g.SetPageUnit(Gdiplus::UnitMillimeter);

        // ペン幅0.4mm
        Gdiplus:Stick out tongueen pen(Gdiplus::Color::Blue, 0.4f);

        // X軸に平行な線を3mm間隔で50本引く
        for (int i = 1; i <= 50; i ++) {
            g.DrawLine(&pen, Gdiplus:Stick out tongueoint(0, 3*i), Gdiplus:Stick out tongueoint(10000, 3*i));
        }
    }
    2008年6月6日 0:40

回答

  • なるほど、自分でどちらのドットに転ばすか決めて、
    そのドットになるmmの値をペン幅に設定すれば良いのですね。

    実験した所きれいに表示されました。

    この方法で行きたいと思います。
    有難う御座いました。m(__)m

    2008年6月6日 9:03

すべての返信

  • 申し訳ありません。
    コロンに続くある一定の英文字が顔文字に変換されるようで大変醜いコードになってしまいました。

    2008年6月6日 0:43
  • ドットの単位は物理的な制約から整数になってしまうので、例えば 4.5 ドットの幅の線を描こうとしても、4 ドットか 5 ドットの線になってしまいます。

    こういう場合は、0.5 ドットの部分を薄く描くなどして見た目を 4.5 ドットっぽくする方法が一般的です。

     

    GDI+ は当然こういった機能も備えており、

    SmoothingMode を変更すればそれなりの線が描けるようになっています。(描画の速度は遅くなります)

    Graphics の SetSmoothingMode をチェックしてみてください。

     

    こんな感じです。

    g.SetSmoothingMode(Gdiplus:: SmoothingModeHighQuality);

     

    # smiley 除けのため、コロンの後にスペースを入れています。

    2008年6月6日 1:45
  • 開発中のソフトの別機能にちょっと影響を与えるため、
    アンチエイリアスは利用しない方向で考えておりました。

    同じペン幅を指定しているので、整数に丸めても同じドットになると
    思っていたのですがどうも違うようですね。

    別機能の方の仕様を変更して貰ってアンチエイリアスを利用する
    方向で考えたいと思います。

    有難う御座いました。

    2008年6月6日 3:44
  • ペン幅の方を調整するというのはいかがでしょう。
    縦と横の DPI が違うと気まずいですが、それなりの効果は得られると思います。

     

    Code Snippet

    // ペン幅の調整
    double oneDot = 25.4 / ((g.GetDpiX() + g.GetDpiY()) / 2.0); // 1ドットの大きさを計算
    Gdiplus::REAL penWidth = static_cast<Gdiplus::REAL>((static_cast<int>(0.4 /* 0.4mm */ / oneDot) + 1) * oneDot);
    Gdiplus::Pen pen(Gdiplus::Color::Blue, penWidth);

     

     

    2008年6月6日 6:12
  • なるほど、自分でどちらのドットに転ばすか決めて、
    そのドットになるmmの値をペン幅に設定すれば良いのですね。

    実験した所きれいに表示されました。

    この方法で行きたいと思います。
    有難う御座いました。m(__)m

    2008年6月6日 9:03