イメージ、描画、およびビジュアルによる塗りつぶし

更新 : 2007 年 11 月

ここでは、ImageBrush オブジェクト、DrawingBrush オブジェクト、および VisualBrush オブジェクトを使用して領域をイメージ、Drawing、または Visual で塗りつぶす方法について説明します。

このトピックには次のセクションが含まれています。

  • 必要条件
  • イメージで領域を塗りつぶす
  • 例 : ビットマップ イメージでオブジェクトを塗りつぶす
  • 描画を使用して領域を塗りつぶす
  • 例 : 描画を使用してオブジェクトを塗りつぶす
  • ビジュアルで領域を塗りつぶす
  • 例 : ビジュアルを使用してオブジェクトを塗りつぶす
  • 例 : 鏡像を作成する
  • TileBrush の機能
  • 関連トピック

必要条件

このトピックを理解するには、Windows Presentation Foundation (WPF) で提供されるさまざまな種類のブラシとその基本的な機能に精通している必要があります。詳細については、「WPF のブラシの概要」を参照してください。

イメージで領域を塗りつぶす

ImageBrush は、ImageSource で領域を塗りつぶします。ImageBrush で使用される最も一般的な種類の ImageSourceBitmapImage で、これは 1 個のビットマップ グラフィックを表します。DrawingImage を使用しても、Drawing オブジェクトによる塗りつぶしは可能ですが、代わりに DrawingBrush を使用する方が簡単です。ImageSource オブジェクトの詳細については、「イメージングの概要」を参照してください。

ImageBrush で塗りつぶすには、BitmapImage を作成し、このオブジェクトを使用してビットマップ コンテンツを読み込みます。次に、BitmapImage を使用して、ImageBrushImageSource プロパティを設定します。最後に、塗りつぶす対象のオブジェクトに ImageBrush を適用します。Extensible Application Markup Language (XAML) では、ImageBrushImageSource プロパティに、読み込むイメージのパスを設定するだけでもかまいません。 

すべての Brush オブジェクトと同様に、ImageBrush は、図形、パネル、コントロール、およびテキストなどのオブジェクトの塗りつぶしに使用できます。ImageBrush で適用できるいくつかの効果を次の図に示します。

ImageBrush によって塗りつぶされたオブジェクト
ImageBrush の出力例

ImageBrush の既定の設定では、対象の領域を完全に塗りつぶすようにイメージが引き伸ばされるので、塗りつぶす領域の縦横比がイメージの縦横比と異なる場合にイメージがゆがむことがあります。この動作を変更するには、Stretch プロパティを既定値の Fill から NoneUniform、または UniformToFill に変更します。ImageBrushTileBrush の型の 1 つであるので、イメージ ブラシで出力領域を塗りつぶす方法を正確に指定でき、パターンを作成することもできます。高度な TileBrush 機能の詳細については、「TileBrush の概要」を参照してください。

例 : ビットマップ イメージでオブジェクトを塗りつぶす

ImageBrush を使用して CanvasBackground を塗りつぶす例を次に示します。

<Page
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation"
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml"
  x:Class="Microsoft.Samples.BrushExamples.ImageBrushExample"
  WindowTitle="ImageBrush Example"
  Background="White">

  <StackPanel>

    <Canvas
      Height="200" Width="300">
      <Canvas.Background>
        <ImageBrush ImageSource="sampleImages\Waterlilies.jpg" />
      </Canvas.Background>
    </Canvas>


  </StackPanel>
</Page>
using System;
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Imaging;

namespace Microsoft.Samples.BrushExamples
{

    public class ImageBrushExample : Page
    {

        public ImageBrushExample()
        {

            StackPanel mainPanel = new StackPanel();
            canvasBackgroundExample(mainPanel);
            this.Content = mainPanel;

        }


        private void canvasBackgroundExample(Panel mainPanel)
        {

            BitmapImage theImage = new BitmapImage
                (new Uri("sampleImages\\Waterlilies.jpg", UriKind.Relative));

            ImageBrush myImageBrush = new ImageBrush(theImage);

            Canvas myCanvas = new Canvas();
            myCanvas.Width = 300;
            myCanvas.Height = 200;
            myCanvas.Background = myImageBrush;

            mainPanel.Children.Add(myCanvas);


        }

    }

}

描画を使用して領域を塗りつぶす

DrawingBrush を使用すると、図形、テキスト、イメージ、およびビデオで領域を塗りつぶすことができます。描画ブラシ内の図形自体も、単色、グラデーション、イメージ、または別の DrawingBrush で塗りつぶすことができます。DrawingBrush のいくつかの使用例を次の図に示します。

DrawingBrush によって塗りつぶされたオブジェクト
DrawingBrush の出力例

DrawingBrush は、Drawing オブジェクトで領域を塗りつぶします。Drawing オブジェクトは、図形、ビットマップ、ビデオ、またはテキスト行などの可視コンテンツを記述します。描画の種類によって、表すコンテンツの種類も異なります。描画オブジェクトの種類を次の一覧に示します。

  • GeometryDrawing - 図形を描画します。

  • ImageDrawing - イメージを描画します。

  • GlyphRunDrawing - テキストを描画します。

  • VideoDrawing - オーディオまたはビデオ ファイルを再生します。

  • DrawingGroup - その他の描画を描画します。他の描画を 1 つの複合描画に結合するには、描画グループを使用します。

Drawing オブジェクトの詳細については、「Drawing オブジェクトの概要」を参照してください。

ImageBrush と同様に、DrawingBrushDrawing を引き伸ばして出力領域を塗りつぶします。この動作をオーバーライドするには、Stretch プロパティを既定の設定である Fill から別の設定に変更します。詳細については、Stretch プロパティを参照してください。

例 : 描画を使用してオブジェクトを塗りつぶす

3 つの楕円の描画を使用してオブジェクトを塗りつぶす方法を次の例に示します。楕円の記述には、GeometryDrawing を使用しています。

<Button Content="A Button">
  <Button.Background>
    <DrawingBrush>
      <DrawingBrush.Drawing>
        <GeometryDrawing Brush="LightBlue">
          <GeometryDrawing.Geometry>
            <GeometryGroup>
              <EllipseGeometry RadiusX="12.5" RadiusY="25" Center="25,50" />
              <EllipseGeometry RadiusX="12.5" RadiusY="25" Center="50,50" />
              <EllipseGeometry RadiusX="12.5" RadiusY="25" Center="75,50" />
            </GeometryGroup>
          </GeometryDrawing.Geometry>
          <GeometryDrawing.Pen>
            <Pen Thickness="1" Brush="Gray" />
          </GeometryDrawing.Pen>
        </GeometryDrawing>
      </DrawingBrush.Drawing>
    </DrawingBrush>
  </Button.Background>
</Button>
// Create a DrawingBrush.
DrawingBrush myDrawingBrush = new DrawingBrush();

// Create a drawing.
GeometryDrawing myGeometryDrawing = new GeometryDrawing();
myGeometryDrawing.Brush = Brushes.LightBlue;
myGeometryDrawing.Pen = new Pen(Brushes.Gray, 1);
GeometryGroup ellipses = new GeometryGroup();
ellipses.Children.Add(new EllipseGeometry(new Point(25,50), 12.5, 25));
ellipses.Children.Add(new EllipseGeometry(new Point(50,50), 12.5, 25));
ellipses.Children.Add(new EllipseGeometry(new Point(75,50), 12.5, 25));

myGeometryDrawing.Geometry = ellipses;
myDrawingBrush.Drawing = myGeometryDrawing;

Button myButton = new Button();
myButton.Content = "A Button";

// Use the DrawingBrush to paint the button's background.
myButton.Background = myDrawingBrush;

ビジュアルで領域を塗りつぶす

すべてのブラシの中で最も用途が広く、多くの機能を持つ VisualBrush は、Visual で領域を塗りつぶします。Visual は低レベルのグラフィックス型で、多数の有用なグラフィカル コンポーネントの先祖として使用されます。たとえば、Window クラス、FrameworkElement クラス、および Control クラスはすべて、Visual オブジェクトの一種です。VisualBrush による領域の塗りつぶしには、Windows Presentation Foundation (WPF) のほぼすべてのグラフィカル オブジェクトが使用可能です。

ms749021.alert_note(ja-jp,VS.90).gifメモ :

VisualBrush は、一種の Freezable オブジェクトですが、その Visual プロパティが null 以外の値に設定されている場合は、フリーズする (読み取り専用にする) ことはできません。

VisualBrushVisual コンテンツを指定するには、2 とおりの方法があります。

  • 新しい Visual を作成し、このビジュアルを使用して VisualBrushVisual プロパティを設定します。例については、後の「例 : ビジュアルを使用してオブジェクトを塗りつぶす」を参照してください。

  • 既存の Visual を使用して、ターゲットの Visual の複製イメージを作成します。次に、VisualBrush を使用して反射や拡大などの効果を作成します。例については、「例 : 反射を作成する」を参照してください。

VisualBrushVisual を新たに定義したときに、その VisualUIElement (パネルやコントロールなど) ならば、AutoLayoutContent プロパティが true に設定されている場合に UIElement およびその子要素に基づいてレイアウト システムが実行されます。ただし、ルートの UIElement は実質的にシステムのその他の部分から切り離され、スタイルや外部レイアウトがこの境界を通過することはできません。したがって、ルートの UIElement のサイズは明示的に指定してください。その唯一の親が VisualBrush であるために、描画される領域に合わせて自身のサイズが自動的に設定されることはないからです。Windows Presentation Foundation (WPF) でのレイアウトの詳細については、「レイアウト システム」を参照してください。

ImageBrushDrawingBrush と同様に、VisualBrush で出力領域を塗りつぶすときはコンテンツが引き伸ばされます。この動作をオーバーライドするには、Stretch プロパティを、既定の設定である Fill から別の設定に変更します。詳細については、Stretch プロパティを参照してください。

例 : ビジュアルを使用してオブジェクトを塗りつぶす

次の例では、いくつかのコントロールと 1 つのパネルを使用して四角形を塗りつぶします。

<Rectangle Width="150" Height="150" Stroke="Black" Margin="5,0,5,0">
  <Rectangle.Fill>
    <VisualBrush>
      <VisualBrush.Visual>
        <StackPanel Background="White">
          <Rectangle Width="25" Height="25" Fill="Red" Margin="2" />
          <TextBlock FontSize="10pt" Margin="2">Hello, World!</TextBlock>
          <Button Margin="2">A Button</Button>
        </StackPanel>
      </VisualBrush.Visual>
    </VisualBrush>
  </Rectangle.Fill>
</Rectangle>
VisualBrush myVisualBrush = new VisualBrush();

// Create the visual brush's contents.
StackPanel myStackPanel = new StackPanel();
myStackPanel.Background = Brushes.White;

Rectangle redRectangle = new Rectangle();
redRectangle.Width = 25;
redRectangle.Height =25; 
redRectangle.Fill = Brushes.Red;
redRectangle.Margin = new Thickness(2);
myStackPanel.Children.Add(redRectangle);

TextBlock someText = new TextBlock();
FontSizeConverter myFontSizeConverter = new FontSizeConverter();
someText.FontSize = (double)myFontSizeConverter.ConvertFrom("10pt");
someText.Text = "Hello, World!";
someText.Margin = new Thickness(2);
myStackPanel.Children.Add(someText);

Button aButton = new Button();
aButton.Content = "A Button";
aButton.Margin = new Thickness(2);
myStackPanel.Children.Add(aButton);

// Use myStackPanel as myVisualBrush's content.
myVisualBrush.Visual = myStackPanel;

// Create a rectangle to paint.
Rectangle myRectangle = new Rectangle();
myRectangle.Width = 150;
myRectangle.Height = 150;
myRectangle.Stroke = Brushes.Black;
myRectangle.Margin = new Thickness(5,0,5,0);

// Use myVisualBrush to paint myRectangle.
myRectangle.Fill = myVisualBrush;

例 : 鏡像を作成する

前の例では、背景として使用するために Visual を新規作成する方法を示しました。VisualBrush を使用して既存のビジュアルを表示することもできます。この機能を使用すると、反射や拡大などのユニークな視覚効果を作成できます。次の例では、VisualBrush を使用して、複数の要素が含まれる Border の鏡像を作成します。この例が生成する出力を次の図に示します。

ビジュアル オブジェクトの鏡像
反映された Visual オブジェクト

using System;
using System.Windows;
using System.Windows.Data;
using System.Windows.Controls;
using System.Windows.Media;
using System.Windows.Media.Effects;
using System.Windows.Media.Imaging;
using System.IO;
using System.Collections.ObjectModel;
using System.Windows.Shapes;
namespace SDKSample
{
    public partial class ReflectionExample : Page
    {
        public ReflectionExample()
        {
            // Create a name scope for the page.
            NameScope.SetNameScope(this, new NameScope());

            this.Background = Brushes.Black;
            StackPanel myStackPanel = new StackPanel();
            myStackPanel.Margin = new Thickness(50);

            Border myReflectedBorder = new Border();
            this.RegisterName("ReflectedVisual", myReflectedBorder);

            // Create a gradient background for the border.
            GradientStop firstStop = new GradientStop();
            firstStop.Offset = 0.0;
            Color firstStopColor = new Color();
            firstStopColor.R = 204;
            firstStopColor.G = 204;
            firstStopColor.B = 255;
            firstStopColor.A = 255;
            firstStop.Color = firstStopColor;
            GradientStop secondStop = new GradientStop();
            secondStop.Offset = 1.0;
            secondStop.Color = Colors.White;

            GradientStopCollection myGradientStopCollection = new GradientStopCollection();
            myGradientStopCollection.Add(firstStop);
            myGradientStopCollection.Add(secondStop);

            LinearGradientBrush myLinearGradientBrush = new LinearGradientBrush();
            myLinearGradientBrush.StartPoint = new Point(0, 0.5);
            myLinearGradientBrush.EndPoint = new Point(1, 0.5);
            myLinearGradientBrush.GradientStops = myGradientStopCollection;

            myReflectedBorder.Background = myLinearGradientBrush;

            // Add contents to the border.
            StackPanel borderStackPanel = new StackPanel();
            borderStackPanel.Orientation = Orientation.Horizontal;
            borderStackPanel.Margin = new Thickness(10);

            TextBlock myTextBlock = new TextBlock();
            myTextBlock.TextWrapping = TextWrapping.Wrap;
            myTextBlock.Width = 200;
            myTextBlock.Text = "Lorem ipsum dolor sit amet, consectetuer adipiscing elit." +
                               " Suspendisse vel ante. Donec luctus tortor sit amet est." +
                               " Nullam pulvinar odio et wisi." +
                               " Pellentesque quis magna. Sed pellentesque." +
                               " Nulla euismod." +
                               "Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.";

            borderStackPanel.Children.Add(myTextBlock);

            StackPanel ellipseStackPanel = new StackPanel();

            Ellipse ellipse1 = new Ellipse();
            ellipse1.Margin = new Thickness(10);
            ellipse1.Height = 50;
            ellipse1.Width = 50;
            ellipse1.Fill = Brushes.Black;
            ellipseStackPanel.Children.Add(ellipse1);
            Ellipse ellipse2 = new Ellipse();
            ellipse2.Margin = new Thickness(10);
            ellipse2.Height = 50;
            ellipse2.Width = 50;
            ellipse2.Fill = Brushes.Black;
            ellipseStackPanel.Children.Add(ellipse2);
            Ellipse ellipse3 = new Ellipse();
            ellipse3.Margin = new Thickness(10);
            ellipse3.Height = 50;
            ellipse3.Width = 50;
            ellipse3.Fill = Brushes.Black;
            ellipseStackPanel.Children.Add(ellipse3);
            borderStackPanel.Children.Add(ellipseStackPanel);

            myReflectedBorder.Child = borderStackPanel;

            // Create divider rectangle
            Rectangle dividerRectangle = new Rectangle();
            dividerRectangle.Height = 1;
            dividerRectangle.Fill = Brushes.Gray;
            dividerRectangle.HorizontalAlignment = HorizontalAlignment.Stretch;

            // Create the object to contain the reflection.
            Rectangle reflectionRectangle = new Rectangle();

            // Bind the height of the rectangle to the border height.
            Binding heightBinding = new Binding();
            heightBinding.ElementName = "ReflectedVisual";
            heightBinding.Path = new PropertyPath(Rectangle.HeightProperty);
            BindingOperations.SetBinding(reflectionRectangle, Rectangle.HeightProperty, heightBinding);

            // Bind the width of the rectangle to the border width.
            Binding widthBinding = new Binding();
            widthBinding.ElementName = "ReflectedVisual";
            widthBinding.Path = new PropertyPath(Rectangle.WidthProperty);
            BindingOperations.SetBinding(reflectionRectangle, Rectangle.WidthProperty, widthBinding);

            // Creates the reflection.
            VisualBrush myVisualBrush = new VisualBrush();
            myVisualBrush.Opacity = 0.75;
            myVisualBrush.Stretch = Stretch.None;
            Binding reflectionBinding = new Binding();
            reflectionBinding.ElementName = "ReflectedVisual";
            BindingOperations.SetBinding(myVisualBrush, VisualBrush.VisualProperty, reflectionBinding);

            ScaleTransform myScaleTransform = new ScaleTransform();
            myScaleTransform.ScaleX = 1;
            myScaleTransform.ScaleY = -1;
            TranslateTransform myTranslateTransform = new TranslateTransform();
            myTranslateTransform.Y = 1;

            TransformGroup myTransformGroup = new TransformGroup();
            myTransformGroup.Children.Add(myScaleTransform);
            myTransformGroup.Children.Add(myTranslateTransform);

            myVisualBrush.RelativeTransform = myTransformGroup;

            reflectionRectangle.Fill = myVisualBrush;

            // Create a gradient background for the border.
            GradientStop firstStop2 = new GradientStop();
            firstStop2.Offset = 0.0;
            Color c1 = new Color();
            c1.R = 0;
            c1.G = 0;
            c1.B = 0;
            c1.A = 255;
            firstStop2.Color = c1;
            GradientStop secondStop2 = new GradientStop();
            secondStop2.Offset = 0.5;
            Color c2 = new Color();
            c2.R = 0;
            c2.G = 0;
            c2.B = 0;
            c2.A = 51;
            firstStop2.Color = c2;
            GradientStop thirdStop = new GradientStop();
            thirdStop.Offset = 0.75;
            Color c3 = new Color();
            c3.R = 0;
            c3.G = 0;
            c3.B = 0;
            c3.A = 0;
            thirdStop.Color = c3;

            GradientStopCollection myGradientStopCollection2 = new GradientStopCollection();
            myGradientStopCollection2.Add(firstStop2);
            myGradientStopCollection2.Add(secondStop2);
            myGradientStopCollection2.Add(thirdStop);

            LinearGradientBrush myLinearGradientBrush2 = new LinearGradientBrush();
            myLinearGradientBrush2.StartPoint = new Point(0.5, 0);
            myLinearGradientBrush2.EndPoint = new Point(0.5, 1);
            myLinearGradientBrush2.GradientStops = myGradientStopCollection2;

            reflectionRectangle.OpacityMask = myLinearGradientBrush2;

            BlurBitmapEffect myBlurBitmapEffect = new BlurBitmapEffect();
            myBlurBitmapEffect.Radius = 1.5;

            reflectionRectangle.BitmapEffect = myBlurBitmapEffect;

            myStackPanel.Children.Add(myReflectedBorder);
            myStackPanel.Children.Add(dividerRectangle);
            myStackPanel.Children.Add(reflectionRectangle);
            this.Content = myStackPanel;

        }
        /*
    <Rectangle 
      Height="{Binding Path=ActualHeight, ElementName=ReflectedVisual}" 
      Width="{Binding Path=ActualWidth, ElementName=ReflectedVisual}">

      <Rectangle.OpacityMask>
        <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
          <GradientStop Color="#FF000000" Offset="0.0" />
          <GradientStop Color="#33000000" Offset="0.5" />
          <GradientStop Color="#00000000" Offset="0.75" />
        </LinearGradientBrush>
      </Rectangle.OpacityMask>

      <Rectangle.BitmapEffect>
        <BlurBitmapEffect Radius="1.5" />
      </Rectangle.BitmapEffect>

    </Rectangle>
  </StackPanel>
</Page>

*/

    }
}
<Page  
  xmlns="https://schemas.microsoft.com/winfx/2006/xaml/presentation" 
  xmlns:x="https://schemas.microsoft.com/winfx/2006/xaml" 
  Background="Black">


  <StackPanel Margin="50">

    <!-- The object to reflect. -->
    <Border Name="ReflectedVisual" Width="400">
      <Border.Background>
        <LinearGradientBrush StartPoint="0,0.5" EndPoint="1,0.5">
          <GradientStop Offset="0.0" Color="#CCCCFF" />
          <GradientStop Offset="1.0" Color="White" />
        </LinearGradientBrush>
      </Border.Background>
      <StackPanel Orientation="Horizontal" Margin="10">        
        <TextBlock TextWrapping="Wrap" Width="200" Margin="10">
          Lorem ipsum dolor sit amet, consectetuer adipiscing elit.
          Suspendisse vel ante. Donec luctus tortor sit amet est.
          Nullam pulvinar odio et wisi.
          Pellentesque quis magna. Sed pellentesque.
          Nulla euismod.
          Pellentesque habitant morbi tristique senectus et netus et malesuada fames ac turpis egestas.
        </TextBlock>
        <StackPanel>
          <Ellipse Margin="10" Height="50" Width="50" Fill="Black" />
          <Ellipse Margin="10" Height="50" Width="50" Fill="Black" />
          <Ellipse Margin="10" Height="50" Width="50" Fill="Black" />
        </StackPanel>
      </StackPanel>
    </Border>

    <Rectangle Height="1" Fill="Gray" HorizontalAlignment="Stretch" />

    <!-- The object to contain the reflection.-->
    <Rectangle 
      Height="{Binding Path=ActualHeight, ElementName=ReflectedVisual}" 
      Width="{Binding Path=ActualWidth, ElementName=ReflectedVisual}">
      <Rectangle.Fill>

        <!-- Creates the reflection. -->
        <VisualBrush 
          Opacity="0.75" Stretch="None"
          Visual="{Binding ElementName=ReflectedVisual}">
          <VisualBrush.RelativeTransform>

            <!-- Flip the reflection. -->
            <TransformGroup>
              <ScaleTransform ScaleX="1" ScaleY="-1" />
              <TranslateTransform  Y="1" />
            </TransformGroup>
          </VisualBrush.RelativeTransform>
        </VisualBrush>
      </Rectangle.Fill>

      <Rectangle.OpacityMask>
        <LinearGradientBrush StartPoint="0.5,0" EndPoint="0.5,1">
          <GradientStop Color="#FF000000" Offset="0.0" />
          <GradientStop Color="#33000000" Offset="0.5" />
          <GradientStop Color="#00000000" Offset="0.75" />
        </LinearGradientBrush>
      </Rectangle.OpacityMask>

      <Rectangle.BitmapEffect>
        <BlurBitmapEffect Radius="1.5" />
      </Rectangle.BitmapEffect>

    </Rectangle>
  </StackPanel>
</Page>

この他の、画面の一部分を拡大する方法や鏡像を作成する方法の例については、「VisualBrush のサンプル」を参照してください。

TileBrush の機能

ImageBrushDrawingBrush、および VisualBrush は、TileBrush オブジェクトの一種です。TileBrush オブジェクトを使用すると、イメージ、描画、またはビジュアルで領域を塗りつぶす方法を細かく制御できます。たとえば、引き伸ばした単一のイメージで領域をただ塗りつぶすのではなく、パターンを作成する一連のイメージ タイルで領域を塗りつぶすことができます。

TileBrush には、コンテンツ、タイル、および出力領域の 3 つの主要コンポーネントがあります。

1 つのタイルを使用する TileBrush のコンポーネント
TileBrush コンポーネント複数のタイルを使用する TileBrush のコンポーネント
並べて表示された TileBrush のコンポーネント

TileBrush オブジェクトの、並べて表示する機能の詳細については、「TileBrush の概要」を参照してください。

参照

処理手順

ImageBrush のサンプル

DrawingBrush のサンプル

VisualBrush のサンプル

概念

TileBrush の概要

WPF のブラシの概要

イメージングの概要

Drawing オブジェクトの概要

不透明マスクの概要

Windows Presentation Foundation のグラフィックス レンダリングの概要

参照

ImageBrush

DrawingBrush

VisualBrush

TileBrush