前提・実現したいこと
タイトル通りOpacityMaskで透明部分を切り出す方法が知りたいです。
ImageやRectangleのプロパティにOpacityMaskというものがあります。
https://czpanel.com/blog/opacitymask-and-resources/
上記のサイトをご覧いただくとわかると思いますが、
塗りつぶしたRectangleにOpacitiMaskとして画像をセットすると、
画像の色のある部分(サイトだとオレンジの部分)が切り取ることができます。
ちなみにオレンジ画像の背景はTransparent(透明)です。
この逆のこと(オレンジの周りが青色になる)をしたいのですがいい方法はありますか?
気になる質問をクリップする
クリップした質問は、後からいつでもMYページで確認できます。
またクリップした質問に回答があった際、通知やメールを受け取ることができます。
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/12/17 11:32
回答1件
0
ベストアンサー
普通に考えるとこの辺を使って、アルファを反転させた画像を作るんでしょうね。
BitmapSource.CopyPixels メソッド (System.Windows.Media.Imaging) | Microsoft Docs
WPFにおける画像のピクセル値への高速アクセス - Qiita
わたしはこういった(めんどくさそうな)ことは嫌いなので、調べている途中で見たこれでやってみました。
wpf - How to Invert Color of XAML PNG Images using C#? - Stack Overflow
注)私はシェーダーについて何ひとつわかっていません。
xml
1<Window 2 x:Class="Questions374313.MainWindow" 3 xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" 4 xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml" 5 xmlns:local="clr-namespace:Questions374313" 6 Width="800" 7 Height="450" 8 Background="MistyRose"> 9 <Window.Resources> 10 11 <!--<BitmapImage x:Key="original" UriSource="orange.png" />--> 12 <!-- オレンジ画像を使う場合↑を生かして、↓をコメント化 --> 13 <DrawingImage x:Key="original"> 14 <DrawingImage.Drawing> 15 <DrawingGroup> 16 <GeometryDrawing Brush="Transparent"> 17 <GeometryDrawing.Geometry> 18 <RectangleGeometry Rect="0,0,300,277" /> 19 </GeometryDrawing.Geometry> 20 </GeometryDrawing> 21 <GeometryDrawing> 22 <GeometryDrawing.Geometry> 23 <GeometryGroup> 24 <EllipseGeometry 25 Center="150,138.5" 26 RadiusX="140" 27 RadiusY="100"> 28 <EllipseGeometry.Transform> 29 <TransformGroup> 30 <ScaleTransform CenterX="150" CenterY="138.5" /> 31 <SkewTransform CenterX="150" CenterY="138.5" /> 32 <RotateTransform Angle="140" CenterX="150" CenterY="138.5" /> 33 <TranslateTransform /> 34 </TransformGroup> 35 </EllipseGeometry.Transform> 36 </EllipseGeometry> 37 </GeometryGroup> 38 </GeometryDrawing.Geometry> 39 <GeometryDrawing.Brush> 40 <LinearGradientBrush> 41 <GradientStop Offset="0.0" Color="#FFDD6200" /> 42 <GradientStop Offset="1.0" Color="#0000" /> 43 </LinearGradientBrush> 44 </GeometryDrawing.Brush> 45 <GeometryDrawing.Pen> 46 <Pen Brush="#FFFFD250" Thickness="20" /> 47 </GeometryDrawing.Pen> 48 </GeometryDrawing> 49 </DrawingGroup> 50 </DrawingImage.Drawing> 51 </DrawingImage> 52 53 <Image x:Key="invert" Source="{StaticResource original}"> 54 <Image.Effect> 55 <local:InvertEffect /> 56 </Image.Effect> 57 </Image> 58 </Window.Resources> 59 60 <UniformGrid 61 HorizontalAlignment="Left" 62 VerticalAlignment="Top" 63 Rows="1"> 64 <UniformGrid.Resources> 65 <Style TargetType="Rectangle"> 66 <Setter Property="Width" Value="300" /> 67 <Setter Property="Height" Value="277" /> 68 <Setter Property="Fill" Value="Blue" /> 69 </Style> 70 </UniformGrid.Resources> 71 72 <GroupBox Header="original"> 73 <Image Source="{StaticResource original}" /> 74 </GroupBox> 75 76 <GroupBox Header="original - OpacityMask"> 77 <Viewbox> 78 <Rectangle> 79 <Rectangle.OpacityMask> 80 <ImageBrush ImageSource="{StaticResource original}" /> 81 </Rectangle.OpacityMask> 82 </Rectangle> 83 </Viewbox> 84 </GroupBox> 85 86 <GroupBox Header="fake"> 87 <Viewbox> 88 <Grid> 89 <Rectangle /> 90 <Rectangle Fill="White"> 91 <Rectangle.OpacityMask> 92 <ImageBrush ImageSource="{StaticResource original}" /> 93 </Rectangle.OpacityMask> 94 </Rectangle> 95 </Grid> 96 </Viewbox> 97 </GroupBox> 98 99 <GroupBox Header="invert - OpacityMask"> 100 <Viewbox> 101 <Rectangle> 102 <Rectangle.OpacityMask> 103 <VisualBrush Visual="{StaticResource invert}" /> 104 </Rectangle.OpacityMask> 105 </Rectangle> 106 </Viewbox> 107 </GroupBox> 108 </UniformGrid> 109</Window>
cs
1using System; 2using System.IO; 3using System.Windows; 4using System.Windows.Media; 5using System.Windows.Media.Effects; 6 7namespace Questions374313 8{ 9 public partial class MainWindow : Window 10 { 11 public MainWindow() => InitializeComponent(); 12 } 13 14 15 // [wpf - How to Invert Color of XAML PNG Images using C#? - Stack Overflow](https://stackoverflow.com/questions/45093399/how-to-invert-color-of-xaml-png-images-using-c) 16 internal class InvertEffect : ShaderEffect 17 { 18 public Brush Input { get => (Brush)GetValue(InputProperty); set => SetValue(InputProperty, value); } 19 public static readonly DependencyProperty InputProperty = RegisterPixelShaderSamplerProperty("Input", typeof(InvertEffect), 0); 20 21 private const string _kshaderAsBase64 = @"AAP///7/HwBDVEFCHAAAAE8AAAAAA///AQAAABwAAAAAAQAASAAAADAAAAADAAAAAQACADgAAAAAAAAAaW5wdXQAq6sEAAwAAQABAAEAAAAAAAAAcHNfM18wAE1pY3Jvc29mdCAoUikgSExTTCBTaGFkZXIgQ29tcGlsZXIgMTAuMQCrUQAABQAAD6AAAIA/AAAAAAAAAAAAAAAAHwAAAgUAAIAAAAOQHwAAAgAAAJAACA+gQgAAAwAAD4AAAOSQAAjkoAIAAAMAAAiAAAD/gQAAAKAFAAADAAgHgAAA/4AAAOSAAQAAAgAICIAAAP+A//8AAA=="; 22 23 private static readonly PixelShader _shader; 24 25 static InvertEffect() 26 { 27 _shader = new PixelShader(); 28 _shader.SetStreamSource(new MemoryStream(Convert.FromBase64String(_kshaderAsBase64))); 29 } 30 31 public InvertEffect() 32 { 33 PixelShader = _shader; 34 UpdateShaderValue(InputProperty); 35 } 36 } 37}
HLSL
1sampler2D input : register(s0); 2 3float4 main(float2 uv : TEXCOORD) : COLOR 4{ 5 float4 color = tex2D(input, uv); 6 float alpha = 1 - color.a; 7 8// color = 1 - color; 9 color.a = alpha; 10 color.rgb *= alpha; 11 12 return color; 13}
ぶっちゃけシェーダーなら何でもありみたいなものでしょうから、こんな回りくどいことをしなくてももっと直接適用できるでしょうが^^;
途中まで調べていたので回答しましたが、「特に意味はない」と言われてしまうと萎えますね^^;
仮絵(DrawingImage
)を作るのが、一番時間がかかりましたw
投稿2021/12/17 15:40
編集2023/07/29 12:42総合スコア9862
バッドをするには、ログインかつ
こちらの条件を満たす必要があります。
2021/12/18 04:10
2021/12/18 04:26
2021/12/20 10:01
2021/12/20 10:23
あなたの回答
tips
太字
斜体
打ち消し線
見出し
引用テキストの挿入
コードの挿入
リンクの挿入
リストの挿入
番号リストの挿入
表の挿入
水平線の挿入
プレビュー
質問の解決につながる回答をしましょう。 サンプルコードなど、より具体的な説明があると質問者の理解の助けになります。 また、読む側のことを考えた、分かりやすい文章を心がけましょう。