DOBON.NET プログラミング道: .NET Framework, VB.NET, C#, Visual Basic, Visual Studio, インストーラ, ...

アンチエイリアス処理をして描画する

図形を描画する時のアンチエイリアス処理

GraphicsオブジェクトのSmoothingModeプロパティの値を変更することにより、直線や曲線を描画するときにアンチエイリアス(スムージング)処理がされるようになります。

SmoothingModeの値をいろいろ変えて直線を描画したときにどのように表示されるか実際に見てみましょう。なお線の描画方法に関しては、「線を描く」をご覧ください。

VB.NET
コードを隠すコードを選択
'Imports System.Drawing
'Imports System.Drawing.Drawing2D
'がソースファイルの一番上に書かれているものとする。

Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    'Graphicsオブジェクトの取得
    Dim g As Graphics = e.Graphics
    'ペンオブジェクトの作成
    Dim p As New Pen(Color.Black)

    '直線を描画
    g.DrawLine(p, 0, 0, 20, 10)

    'SmoothingModeにAntiAlias
    '(アンチエイリアス処理されたレタリング)を指定する
    g.SmoothingMode = SmoothingMode.AntiAlias
    '直線を描画
    g.DrawLine(p, 10, 0, 30, 10)

    'SmoothingModeにDefault
    '(既定のモード)を指定する
    g.SmoothingMode = SmoothingMode.Default
    '直線を描画
    g.DrawLine(p, 20, 0, 40, 10)

    'SmoothingModeにHighQuality
    '(高品質で低速なレンダリング)を指定する
    g.SmoothingMode = SmoothingMode.HighQuality
    '直線を描画
    g.DrawLine(p, 30, 0, 50, 10)

    'SmoothingModeにHighSpeed
    '(高速で、低品質のレンダリング)を指定する
    g.SmoothingMode = SmoothingMode.HighSpeed
    '直線を描画
    g.DrawLine(p, 40, 0, 60, 10)

    'SmoothingModeにNone
    '(アンチエイリアス処理しない)を指定する
    g.SmoothingMode = SmoothingMode.None
    '直線を描画
    g.DrawLine(p, 50, 0, 70, 10)

    p.Dispose()
End Sub
C#
コードを隠すコードを選択
//using System.Drawing;
//using System.Drawing.Drawing2D;
//がソースファイルの一番上に書かれているものとする。

protected override void OnPaint(PaintEventArgs e)
{
    //Graphicsオブジェクトの取得
    Graphics g = e.Graphics;
    //ペンオブジェクトの作成
    Pen p = new Pen(Color.Black);

    //直線を描画
    g.DrawLine(p, 0, 0, 20, 10);

    //SmoothingModeにAntiAlias
    //(アンチエイリアス処理されたレタリング)を指定する
    g.SmoothingMode = SmoothingMode.AntiAlias;
    //直線を描画
    g.DrawLine(p, 10, 0, 30, 10);

    //SmoothingModeにDefault
    //(既定のモード)を指定する
    g.SmoothingMode = SmoothingMode.Default;
    //直線を描画
    g.DrawLine(p, 20, 0, 40, 10);

    //SmoothingModeにHighQuality
    //(高品質で低速なレンダリング)を指定する
    g.SmoothingMode = SmoothingMode.HighQuality;
    //直線を描画
    g.DrawLine(p, 30, 0, 50, 10);

    //SmoothingModeにHighSpeed
    //(高速で、低品質のレンダリング)を指定する
    g.SmoothingMode = SmoothingMode.HighSpeed;
    //直線を描画
    g.DrawLine(p, 40, 0, 60, 10);

    //SmoothingModeにNone
    //(アンチエイリアス処理しない)を指定する
    g.SmoothingMode = SmoothingMode.None;
    //直線を描画
    g.DrawLine(p, 50, 0, 70, 10);

    p.Dispose();
}

私の環境では、上のコードを実行すると、次のように表示されました(10倍に拡大しています)。これを見るとアンチエイリアス処理されて描画されているのは、SmoothingMode.AntiAliasとSmoothingMode.HighQualityだけで、この両者にもこれといった違いはないようです。(.NET Framework 1.1、2.0で確認)

PixelOffsetModeプロパティを指定する

SmoothingModeプロパティによりアンチエイリアス処理されている時、PixelOffsetModeプロパティでレンダリング時のピクセルのオフセット方法を指定することにより、さらに品質が向上します。

先ほどと同様に、SmoothingModeがAntiAliasの時にPixelOffsetModeプロパティの値を変えてみて直線を描画してみましょう。

VB.NET
コードを隠すコードを選択
'Imports System.Drawing
'Imports System.Drawing.Drawing2D
'がソースファイルの一番上に書かれているものとする。

Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    'Graphicsオブジェクトの取得
    Dim g As Graphics = e.Graphics
    'ペンオブジェクトの作成
    Dim p As New Pen(Color.Black)

    'SmoothingModeにAntiAliasを指定する
    g.SmoothingMode = SmoothingMode.AntiAlias
    '直線を描画
    g.DrawLine(p, 10, 0, 30, 10)

    'PixelOffsetModeにDefault(既定のモード)を指定する
    g.PixelOffsetMode = PixelOffsetMode.Default
    '直線を描画
    g.DrawLine(p, 20, 0, 40, 10)

    'PixelOffsetModeにHalf(高速アンチエイリアス処理用に、
    'ピクセルを水平と垂直の両方向に-.5 単位だけオフセットする)を指定する
    g.PixelOffsetMode = PixelOffsetMode.Half
    '直線を描画
    g.DrawLine(p, 30, 0, 50, 10)

    'PixelOffsetModeにHighQuality(高品質で低速なレンダリング)を指定する
    g.PixelOffsetMode = PixelOffsetMode.HighQuality
    '直線を描画
    g.DrawLine(p, 40, 0, 60, 10)

    'PixelOffsetModeにHighSpeed(高速で低品質のレンダリング)を指定する
    g.PixelOffsetMode = PixelOffsetMode.HighSpeed
    '直線を描画
    g.DrawLine(p, 50, 0, 70, 10)

    'PixelOffsetModeにNone(ピクセルをオフセットしない)を指定する
    g.PixelOffsetMode = PixelOffsetMode.None
    '直線を描画
    g.DrawLine(p, 60, 0, 80, 10)

    p.Dispose()
End Sub
C#
コードを隠すコードを選択
//using System.Drawing;
//using System.Drawing.Drawing2D;
//がソースファイルの一番上に書かれているものとする。

protected override void OnPaint(PaintEventArgs e)
{
    //Graphicsオブジェクトの取得
    Graphics g = e.Graphics;
    //ペンオブジェクトの作成
    Pen p = new Pen(Color.Black);

    //PixelOffsetModeにAntiAliasを指定する
    g.SmoothingMode = SmoothingMode.AntiAlias;
    //直線を描画
    g.DrawLine(p, 10, 0, 30, 10);

    //PixelOffsetModeにDefault(既定のモード)を指定する
    g.PixelOffsetMode = PixelOffsetMode.Default;
    //直線を描画
    g.DrawLine(p, 20, 0, 40, 10);

    //PixelOffsetModeにHalf(高速アンチエイリアス処理用に、
    //ピクセルを水平と垂直の両方向に-.5 単位だけオフセットする)を指定する
    g.PixelOffsetMode = PixelOffsetMode.Half;
    //直線を描画
    g.DrawLine(p, 30, 0, 50, 10);

    //PixelOffsetModeにHighQuality(高品質で低速なレンダリング)を指定する
    g.PixelOffsetMode = PixelOffsetMode.HighQuality;
    //直線を描画
    g.DrawLine(p, 40, 0, 60, 10);

    //PixelOffsetModeにHighSpeed(高速で低品質のレンダリング)を指定する
    g.PixelOffsetMode = PixelOffsetMode.HighSpeed;
    //直線を描画
    g.DrawLine(p, 50, 0, 70, 10);

    //PixelOffsetModeにNone(ピクセルをオフセットしない)を指定する
    g.PixelOffsetMode = PixelOffsetMode.None;
    //直線を描画
    g.DrawLine(p, 60, 0, 80, 10);

    p.Dispose();
}

上のコードを実行すると、次のように表示されます(10倍に拡大しています)。これによるとPixelOffsetModeプロパティの効果が見られるのは、PixelOffsetMode.HalfとPixelOffsetMode.HighQualityだけで、この両者にはこれといった違いは見られません。(.NET Framework 1.1、2.0で確認)

結論

以上のことから、アンチエイリアス処理をするにはGraphicsのSmoothingModeをAntiAliasまたはHighQualityとし、さらにピクセルをオフセットするにはPixelOffsetModeをHalfまたはHighQualityにすればよいということが分かります。

文字列を描画する時のアンチエイリアス処理

文字列の描画におけるアンチエイリアス処理は、Graphics.TextRenderingHintプロパティで指定します。ヘルプによると、TextRenderingHintプロパティに指定できるTextRenderingHint列挙体の値とその機能は次のようになっています。

メンバ名 説明
AntiAlias アンチエイリアス処理されたグリフ ビットマップを使用して、ヒンティングなしに各文字を描画することを指定します。アンチエイリアスによって品質が向上します。ヒンティングがオフにされるため、ステム幅の違いが目立ちます。
AntiAliasGridFit アンチエイリアス処理されたグリフ ビットマップを使用して、ヒンティングありで各文字を描画することを指定します。アンチエイリアスによってより高い品質が得られますが、パフォーマンスは大きく低下します。
ClearTypeGridFit グリフ CT ビットマップを使用して、ヒンティングありで各文字を描画することを指定します。最高の品質設定です。ClearType テキスト フォント機能を利用するときに使用します。
SingleBitPerPixel グリフ ビットマップを使用して、各文字を描画することを指定します。ヒンティングは使用されません。
SingleBitPerPixelGridFit グリフ ビットマップを使用して、各文字を描画することを指定します。ヒンティングを使用して、文字のステム部分と曲線部分の見た目を向上します。
SystemDefault グリフ ビットマップを使用し、システムの既定のレンダリング ヒントで各文字を描画することを指定します。ユーザーがシステムで選択した、すべてのフォント スムージング設定を使用してテキストを描画します。

具体例で、TextRenderingHintの値をいろいろ変えて文字列を描画したときにどのように表示されるか実際に見てみます。なお、文字列を描画させる方法が分からないという方は、まず「文字を書く」をご覧ください。

VB.NET
コードを隠すコードを選択
'Imports System.Drawing
'Imports System.Drawing.Drawing2D
'Imports System.Drawing.Text
'がソースファイルの一番上に書かれているものとする。

Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
    'Graphicsオブジェクトの取得
    Dim g As Graphics = e.Graphics

    'フォントオブジェクトの作成
    Dim f As New Font("Times New Roman", 12)

    'TextRenderingHintをAntiAliasして文字列を描画
    g.TextRenderingHint = TextRenderingHint.AntiAlias
    g.DrawString("DOBON.NET", f, Brushes.Black, 0, 0)

    'TextRenderingHintをAntiAliasGridFitして文字列を描画
    g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit
    g.DrawString("DOBON.NET", f, Brushes.Black, 0, 15)

    'TextRenderingHintをClearTypeGridFitして文字列を描画
    g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit
    g.DrawString("DOBON.NET", f, Brushes.Black, 0, 30)

    'TextRenderingHintをSingleBitPerPixelして文字列を描画
    g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel
    g.DrawString("DOBON.NET", f, Brushes.Black, 0, 45)

    'TextRenderingHintをSingleBitPerPixelGridFitして文字列を描画
    g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit
    g.DrawString("DOBON.NET", f, Brushes.Black, 0, 60)

    'TextRenderingHintをSystemDefaultして文字列を描画
    g.TextRenderingHint = TextRenderingHint.SystemDefault
    g.DrawString("DOBON.NET", f, Brushes.Black, 0, 75)

    f.Dispose();
End Sub
C#
コードを隠すコードを選択
//using System.Drawing;
//using System.Drawing.Drawing2D;
//using System.Drawing.Text;
//がソースファイルの一番上に書かれているものとする。

protected override void OnPaint(PaintEventArgs e)
{
    //Graphicsオブジェクトの取得
    Graphics g = e.Graphics;

    //フォントオブジェクトの作成
    Font f = new Font("Times New Roman", 12);

    //TextRenderingHintをAntiAliasして文字列を描画
    g.TextRenderingHint = TextRenderingHint.AntiAlias;
    g.DrawString("DOBON.NET", f, Brushes.Black, 0, 0);

    //TextRenderingHintをAntiAliasGridFitして文字列を描画
    g.TextRenderingHint = TextRenderingHint.AntiAliasGridFit;
    g.DrawString("DOBON.NET", f, Brushes.Black, 0, 15);

    //TextRenderingHintをClearTypeGridFitして文字列を描画
    g.TextRenderingHint = TextRenderingHint.ClearTypeGridFit;
    g.DrawString("DOBON.NET", f, Brushes.Black, 0, 30);

    //TextRenderingHintをSingleBitPerPixelして文字列を描画
    g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
    g.DrawString("DOBON.NET", f, Brushes.Black, 0, 45);

    //TextRenderingHintをSingleBitPerPixelGridFitして文字列を描画
    g.TextRenderingHint = TextRenderingHint.SingleBitPerPixelGridFit;
    g.DrawString("DOBON.NET", f, Brushes.Black, 0, 60);

    //TextRenderingHintをSystemDefaultして文字列を描画
    g.TextRenderingHint = TextRenderingHint.SystemDefault;
    g.DrawString("DOBON.NET", f, Brushes.Black, 0, 75);

    f.Dispose();
}

上のコードを実行すると、私の環境(Windows XP + .NET Framework 2.0)では次のように表示されました(5倍に拡大しています)。これを見る限りでは、アンチエイリアス処理されているのはAntiAliasとClearTypeのみで、AntiAliasとClearTypeとSingleBitPerPixel以外はどれも同じように描画されました。(環境により異なります。例えば、Windows XP以上でなければ、ClearTypeテキストフォント機能は有効になりません。)

文字列を描画する時のアンチエイリアス処理

なお、TextRenderingHintの場合でもSmoothingModeの時と同様、PixelOffsetModeプロパティにより、品質を向上することが出来ます。

テキストのアンチエイリアシングに関して、「テキストのアンチエイリアシング」でも説明されていますので、そちらも参考にしてください。

  • 履歴:
  • 2007/1/15 .NET Framework 2.0に関する記述を追加。

注意:この記事では、基本的な事柄の説明が省略されているかもしれません。初心者の方は、特に以下の点にご注意ください。

  • このサイトで紹介されているコードの多くは、例外処理が省略されています。例外処理については、こちらをご覧ください。
  • コードの先頭に記述されている「Imports ??? がソースファイルの一番上に書かれているものとする」(C#では、「using ???; がソースファイルの一番上に書かれているものとする」)の意味が分からないという方は、こちらをご覧ください。
  • .NET Tipsをご利用いただく際は、注意事項をお守りください。