午後わてんのブログ

ベランダ菜園とWindows用アプリ作成(WPFとC#)

切り抜きClip、GeometryGroupとCombinedGeometry

f:id:gogowaten:20191214103031p:plain

最大3つのGeometryを組み合わせてClip
GeometryGroupではFillRule
CombinedGeometryではGeometryCombineModeをいくつか組み合わせて
四角形をClip表示してみた
 
 
 
コントロール要素のClipプロパティにGeometryを指定すると切り抜き表示になる
 
アプリ自身のClipに直径500の円のGeometryを指定
this.Clip = new EllipseGeometry(new Rect(0, 0, 500, 500));
これで実行すると
イメージ 2
円形に切り抜き
表示されない部分は透明じゃなくて黒になるんだなあ
 
 
複数のGeometryを組み合わせて使い時は
GeometryGroup、CombinedGeometry
このどちらかでできる
 
重なった部分の表示の仕方を指定する
GeometryGroupはFillRuleで
EvenOdd
Nonzero
のどちらか
 
CombinedGeometryはGeometryCombineModeで
Exclude 除外する、抜かす
Intersect 交わる、交差、横切る
Union 結合、合併
4種類のモードでレッツコンバイン
 
 
元の形と単体クリップ
イメージ 3
原型とそのClipに用意した3つのGeometryを単体で使って表示したところ

用意した3つのGeometry
clip1 = RectangleGeometry(new Rect(10, 10, 60, 90));
clip2 = EllipseGeometry(new Rect(0, 0, 60, 60));
clip3 = EllipseGeometry(new Rect(50, 0, 60, 60));
 
 
 
GeometryGroup
イメージ 4
GeometryGroupで複数のGeometryをまとめてClip
FillRuleで塗り方が変化する
 
イメージ 5
まとめるときはChildren.Addで追加していく、わかりやすい
 
 
 
CombinedGeometry
イメージ 6
Clip1+Clip2をCombineModeを変えて表示
 
UnionはGeometryGroupのFillRule.Nonzeroと同じ
XorはGeometryGroupのFillRule.EvenOddと同じ
になった
 
イメージ 7
コンストラクタでModeと2つのGeometryを指定できるのでラク
 
 
 
CombinedGeometryで3つのGeometry
イメージ 8
これもUnionはNonzero、XorはEvenOddと同じ結果になった
 
 
CombineGeometryで3つ以上のGeometryをまとめるときは
イメージ 9
たぶんこうかな、2つまでしか指定できないみたい
 
イメージ 10
プロパティの方でもわざわざGeometry1,2って番号が振ってあるし
Addとかもなさそう
 
CombinedGeometry別モードとの組み合わせ
イメージ 11
使いこなすのは難しそうだけどいろいろできる
 
デザイン画面
MainWindow.xaml

f:id:gogowaten:20191214103101p:plain

 
MainWindow.xaml.cs
using System.Windows;
using System.Windows.Controls;
using System.Windows.Media;
//第9回 WPFの「グラフィックス」を学ぼう(2/2):連載:WPF入門 - @IT
//https://www.atmarkit.co.jp/ait/articles/1102/02/news100_2.html

namespace _20190330_Clip切り抜き
{
    public partial class MainWindow : Window
    {
        public MainWindow()
        {
            InitializeComponent();

            MyClip();
        }
        private void MyClip()
        {
            //clip用Geometry
            var clip1 = new RectangleGeometry(new Rect(10, 10, 60, 90));
            var clip2 = new EllipseGeometry(new Rect(0, 0, 60, 60));
            var clip3 = new EllipseGeometry(new Rect(50, 0, 60, 60));

            //  1clip
            MyWrapPanel1.Children.Add(CreateBorderWithClip(null));//clipなしの原型
            MyWrapPanel1.Children.Add(CreateBorderWithClip(clip1));
            MyWrapPanel1.Children.Add(CreateBorderWithClip(clip2));
            MyWrapPanel1.Children.Add(CreateBorderWithClip(clip3));



            GeometryGroup geoGroup;
            //  2clip
            geoGroup = new GeometryGroup();
            geoGroup.Children.Add(clip1);
            geoGroup.Children.Add(clip2);
            geoGroup.FillRule = FillRule.EvenOdd;//初期値
            MyWrapPanel2.Children.Add(CreateBorderWithClip(geoGroup));

            geoGroup = new GeometryGroup();
            geoGroup.Children.Add(clip1);
            geoGroup.Children.Add(clip2);
            geoGroup.FillRule = FillRule.Nonzero;
            MyWrapPanel2.Children.Add(CreateBorderWithClip(geoGroup));

            //  3clip
            geoGroup = new GeometryGroup();
            geoGroup.Children.Add(clip1);
            geoGroup.Children.Add(clip2);
            geoGroup.Children.Add(clip3);
            geoGroup.FillRule = FillRule.EvenOdd;
            MyWrapPanel2.Children.Add(CreateBorderWithClip(geoGroup));

            geoGroup = new GeometryGroup();
            geoGroup.Children.Add(clip1);
            geoGroup.Children.Add(clip2);
            geoGroup.Children.Add(clip3);
            geoGroup.FillRule = FillRule.Nonzero;
            MyWrapPanel2.Children.Add(CreateBorderWithClip(geoGroup));



            CombinedGeometry comboGeo;
            //  2clip
            comboGeo = new CombinedGeometry(GeometryCombineMode.Exclude, clip1, clip2);
            MyWrapPanel3.Children.Add(CreateBorderWithClip(comboGeo));

            comboGeo = new CombinedGeometry(GeometryCombineMode.Intersect, clip1, clip2);
            MyWrapPanel3.Children.Add(CreateBorderWithClip(comboGeo));

            comboGeo = new CombinedGeometry(GeometryCombineMode.Union, clip1, clip2);
            MyWrapPanel3.Children.Add(CreateBorderWithClip(comboGeo));

            comboGeo = new CombinedGeometry(GeometryCombineMode.Xor, clip1, clip2);
            MyWrapPanel3.Children.Add(CreateBorderWithClip(comboGeo));


            //  3clip   同じモードを2回
            comboGeo = new CombinedGeometry(GeometryCombineMode.Exclude, clip1, clip2);
            comboGeo = new CombinedGeometry(GeometryCombineMode.Exclude, comboGeo, clip3);
            MyWrapPanel4.Children.Add(CreateBorderWithClip(comboGeo));

            comboGeo = new CombinedGeometry(GeometryCombineMode.Intersect, clip1, clip2);
            comboGeo = new CombinedGeometry(GeometryCombineMode.Intersect, comboGeo, clip3);
            MyWrapPanel4.Children.Add(CreateBorderWithClip(comboGeo));

            comboGeo = new CombinedGeometry(GeometryCombineMode.Union, clip1, clip2);
            comboGeo = new CombinedGeometry(GeometryCombineMode.Union, comboGeo, clip3);
            MyWrapPanel4.Children.Add(CreateBorderWithClip(comboGeo));

            comboGeo = new CombinedGeometry(GeometryCombineMode.Xor, clip1, clip2);
            comboGeo = new CombinedGeometry(GeometryCombineMode.Xor, comboGeo, clip3);
            MyWrapPanel4.Children.Add(CreateBorderWithClip(comboGeo));


            //  3clip   Excludeと他
            comboGeo = new CombinedGeometry(GeometryCombineMode.Exclude, clip1, clip2);
            comboGeo = new CombinedGeometry(GeometryCombineMode.Intersect, comboGeo, clip3);
            MyWrapPanel5.Children.Add(CreateBorderWithClip(comboGeo));

            comboGeo = new CombinedGeometry(GeometryCombineMode.Exclude, clip1, clip2);
            comboGeo = new CombinedGeometry(GeometryCombineMode.Union, comboGeo, clip3);
            MyWrapPanel5.Children.Add(CreateBorderWithClip(comboGeo));

            comboGeo = new CombinedGeometry(GeometryCombineMode.Exclude, clip1, clip2);
            comboGeo = new CombinedGeometry(GeometryCombineMode.Xor, comboGeo, clip3);
            MyWrapPanel5.Children.Add(CreateBorderWithClip(comboGeo));


            //  3clip   Intersectと他
            comboGeo = new CombinedGeometry(GeometryCombineMode.Intersect, clip1, clip2);
            comboGeo = new CombinedGeometry(GeometryCombineMode.Exclude, comboGeo, clip3);
            MyWrapPanel6.Children.Add(CreateBorderWithClip(comboGeo));

            comboGeo = new CombinedGeometry(GeometryCombineMode.Intersect, clip1, clip2);
            comboGeo = new CombinedGeometry(GeometryCombineMode.Union, comboGeo, clip3);
            MyWrapPanel6.Children.Add(CreateBorderWithClip(comboGeo));

            comboGeo = new CombinedGeometry(GeometryCombineMode.Intersect, clip1, clip2);
            comboGeo = new CombinedGeometry(GeometryCombineMode.Xor, comboGeo, clip3);
            MyWrapPanel6.Children.Add(CreateBorderWithClip(comboGeo));

        }
        private Border CreateBorderWithClip(Geometry clip)
        {
            var r = new Border
            {
                Clip = clip,
                Background = Brushes.MediumAquamarine,
                BorderBrush = Brushes.Orchid,
                BorderThickness = new Thickness(4.0),
                Width = 100,
                Height = 100,
                Margin = new Thickness(4.0, 10.0, 4.0, 60.0),
            };
            return r;
        }
    }
}
 
参照したところ
第9回 WPFの「グラフィックス」を学ぼう(2/2):連載:WPF入門 - @IT
https://www.atmarkit.co.jp/ait/articles/1102/02/news100_2.html
 
 
ギットハブ
 
 
関連記事
2019/3/25は一週間くらい前
色相環画像作成、WriteableBitmapとImage.Clip ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15913863.html
このときの切り抜きはPathGeometryのAddGeometryで2つのEllipseGeometryをまとめていた、今回みたくGeometryGroupを使う必要ない?
 
 
2019/04/04は明後日
画像の色相を円形ヒストグラム、扇形(パイ型)グラフで表示するアプリできた ( ソフトウェア ) - 午後わてんのブログ - Yahoo!ブログ
https://blogs.yahoo.co.jp/gogowaten/15923169.html
イメージ 13
 
 
2年後