WisdomSoft - for your serial experiences.

6.3 画像ブラシ

TextureBrush クラスを用いて、任意の画像(Image オブジェクト)をブラシに適用します。閉じた領域の内部を、画像で塗りつぶすことができます。

6.3.1 イメージを使ったブラシ

閉じた図形の内部を塗りつぶす Brush クラスを継承したブラシの中で、イメージを使って内部を塗りつぶすテクスチャブラシがあります。スタンプのように小さなアイコンのようなイメージを繰り返して図形内部を任意の模様で塗りつぶすことができます。テクスチャブラシには System.Drawing.TextureBrush クラスを使います。

System.Drawing.TextureBrush クラス
System.Object
    System.MarshalByRefObject
        System.Drawing.Brush
            System.Drawing.TextureBrush
public sealed class TextureBrush : Brush

TextureBrush クラスのコンストラクタには、図形の内部を塗りつぶすために使う Image オブジェクトを設定しなければなりません。

TextureBrush クラスのコンストラクタ
public TextureBrush(Image image)

image パラメータにはテクスチャとして利用するイメージを指定します。デフォルトでは、ここで指定したイメージが水平方向と垂直方向に繰り返し貼り付けられることで図形の内部を塗りつぶします。

もし、TextureBrush オブジェクトに設定されているイメージを知りたければ Image プロパティから取得することができます

TextureBrush クラス Image プロパティ
public Image Image { get; }

このプロパティは、コンストラクタで指定した塗りつぶしに利用する Image オブジェクトを返します。

コード1
using System.Drawing;
using System.Windows.Forms;

public class Test : Form
{
	private Image image;
	protected override void OnPaint(PaintEventArgs e)
	{
		base.OnPaint (e);
		if (image == null) image = Image.FromFile("texture.bmp");

		Brush brush = new TextureBrush(image);
		e.Graphics.FillEllipse(
			brush, 0, 0, ClientSize.Width, ClientSize.Height);
	}

	protected override void OnResize(System.EventArgs e)
	{
		base.OnResize (e);
		Invalidate();
	}

	static void Main() 
	{
		Application.Run(new Test());
	}
}
実行結果
コード1 実行結果

コード1は、FillEllipse() メソッドで塗りつぶす楕円のブラシにテクスチャブラシを使っています。テクスチャブラシには、猫の足跡のような小さなイメージを使っています。この小さなイメージを水平・垂直方向に繰り返しながら塗りつぶしていることを確認できます。レンガの壁や衣服など、特定の模様が繰り返している物を描画するときに使うことができます。

また、比較的大きなイメージの一部をテクスチャブラシの模様として使いたい場合は次のコンストラクタを使います。

TextureBrush クラスのコンストラクタ
public TextureBrush(Image image, Rectangle dstRect)

image パラメータにはテクスチャとして利用するイメージを、dstRect パラメータには使用するイメージの矩形範囲を指定します。比較的大きなイメージの一部だけを繰りかしたい場合に指定します。dstRect パラメータを指定しない場合はイメージ全体が使われます。

コード2
using System.Drawing;
using System.Windows.Forms;

public class Test : Form
{
	private Image image;
	protected override void OnPaint(PaintEventArgs e)
	{
		base.OnPaint (e);
		if (image == null) image = Image.FromFile("test.bmp");

		Brush brush = new TextureBrush(image, new Rectangle(100, 50, 100, 100));
		e.Graphics.FillEllipse(
			brush, 0, 0, ClientSize.Width, ClientSize.Height);
	}

	protected override void OnResize(System.EventArgs e)
	{
		base.OnResize (e);
		Invalidate();
	}

	static void Main() 
	{
		Application.Run(new Test());
	}
}
実行結果
コード2 実行結果

コード2は、大きなイメージの一部だけをテクスチャブラシとして利用しています。TextureBrush コンストラクタでテクスチャブラシとして利用するイメージの範囲を設定していることに注目してください。

さらに、TextureBrush コンストラクタ、または WrapMode プロパティでイメージの水平・垂直方向への繰り返しをどのように行うかを指定することができます。デフォルトでは、イメージをそのまま水平・垂直方向に繰り返していました。

TextureBrush クラスのコンストラクタ
public TextureBrush(Image image, WrapMode wrapMode)
public TextureBrush(Image image, WrapMode wrapMode, Rectangle dstRect)
TextureBrush クラス WrapMode プロパティ
public WrapMode WrapMode { get; set; }

コンストラクタの wrapMode パラメータや、WrapMode プロパティには System.Drawing.Drawing2D.WrapMode 列挙体のメンバを指定します。

System.Drawing.Drawing2D.WrapMode 列挙体
[Serializable]
public enum WrapMode

WrapMode 列挙体には次のようなメンバが定義されています。

表1 WrapMode 列挙体のメンバ
メンバ名 説明
Clamp オブジェクトの端に揃える。
Tile 並べて表示。
TileFlipX 水平方向に反転し、それを並べて表示。
TileFlipXY 水平および垂直方向に反転し、それを並べて表示。
TileFlipY 垂直方向に反転し、それを並べて表示。

テクスチャブラシのデフォルトは Tile メンバが指定されています。TileFilp から始まるメンバを指定した場合は、水平・垂直方向にイメージを反転して並べることができます。Clamp メンバは塗りつぶす図形の左上隅にイメージを一度描画するだけで、繰り返しは行われません。反転を使ったテクスチャブラシをうまく利用することで、絨毯などで見かける対になった絵柄のデザインで内部を塗りつぶすことができます。

コード3
using System.Drawing;
using System.Drawing.Drawing2D;
using System.Windows.Forms;

public class Test : Form
{
	private Image image;
	protected override void OnPaint(PaintEventArgs e)
	{
		base.OnPaint (e);
		if (image == null) image = Image.FromFile("texture.bmp");

		Brush brush1 = new TextureBrush(image, WrapMode.Clamp);
		Brush brush2 = new TextureBrush(image, WrapMode.Tile);
		Brush brush3 = new TextureBrush(image, WrapMode.TileFlipX);
		Brush brush4 = new TextureBrush(image, WrapMode.TileFlipY);
		Brush brush5 = new TextureBrush(image, WrapMode.TileFlipXY);

		e.Graphics.FillRectangle(brush1, 0, 0, 200, 200);
		e.Graphics.FillEllipse(brush2, 200, 0, 200, 200);
		e.Graphics.FillEllipse(brush3, 400, 0, 200, 200);
		e.Graphics.FillEllipse(brush4, 0, 200, 200, 200);
		e.Graphics.FillEllipse(brush5, 200, 200, 200, 200);
	}

	static void Main() 
	{
		Application.Run(new Test());
	}
}
実行結果
コード3 実行結果

コード3では、WrapMode 列挙体の各メンバごとにテクスチャブラシを作成し、それぞれのブラシで楕円の内部を塗りつぶしています。最初の塗りつぶしは繰り返しを行わない WrapMode.Clamp を使ったテクスチャなので、分かりやすくするためにここだけは FillRectangle() メソッドによる矩形の塗りつぶしになっています。クライアント領域の左上に、一度だけイメージが描画されています。

そのほかの楕円はすべて、WrapMode の繰り返しを行うメンバで描画したものです。イメージが、水平方向や垂直方向に反転して繰り返し並べられていることを確認することができます。