読者です 読者をやめる 読者になる 読者になる

Image に OpacityMask

不思議な動きを発見したのでメモです。

画像などを床に反射しているような感じにする鏡面効果をだすために、同じ画像をもう一枚用意し上下逆転させます。

<Image x:Name="sourceImage" Width="160" Height="160" Canvas.Left="80" Canvas.Top="80" Source="image.png"/>
<Image x:Name="reflectionImage" Width="160" Height="160" Canvas.Left="80" Canvas.Top="380" Source="image.png">
  <Image.RenderTransform>
    <TransformGroup>
      <ScaleTransform ScaleX="1" ScaleY="-1"/>
      <SkewTransform AngleX="0" AngleY="0"/>
      <RotateTransform Angle="0"/>
      <TranslateTransform X="0" Y="0"/>
    </TransformGroup>
  </Image.RenderTransform>
</Image>

で、この反転された画像に対して OpactityMask を適用します。こんな感じ。グラデーションかけてます。

<Image x:Name="reflectionImage" Width="160" Height="160" Canvas.Left="80" Canvas.Top="380" Source="image.png">
  <Image.RenderTransform>
    <TransformGroup>
      <ScaleTransform ScaleX="1" ScaleY="-1"/>
      <SkewTransform AngleX="0" AngleY="0"/>
      <RotateTransform Angle="0"/>
      <TranslateTransform X="0" Y="0"/>
    </TransformGroup>
  </Image.RenderTransform>
  <Image.OpacityMask>
    <LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1">
      <GradientStop Color="#99000000" Offset="0"/>
      <GradientStop Color="#00FFFFFF" Offset="1"/>
    </LinearGradientBrush>
  </Image.OpacityMask>
</Image>

が、こうするとなぜか反転させた画像が表示されなくなりました。。どうやら OpacityMask を画像に指定すると表示されなくなるみたいです。
試しに反転してない画像のタグを消して、ブラウザがちゃんと画像をロードしてるか見てみたのですが、ちゃんとロードしていたのでどうやら Silverlight が描画しきれていないようです。
ちなみに WPF であればこれで表示されます。
仕方がないので Canvas でくくって、その Canvas に OpacityMask をかけてみました。

<Canvas>
  <Image x:Name="reflectionImage" Width="160" Height="160" Canvas.Left="80" Canvas.Top="380" Source="image.png">
    <Image.RenderTransform>
      <TransformGroup>
        <ScaleTransform ScaleX="1" ScaleY="-1"/>
        <SkewTransform AngleX="0" AngleY="0"/>
        <RotateTransform Angle="0"/>
        <TranslateTransform X="0" Y="0"/>
      </TransformGroup>
    </Image.RenderTransform>
  </Image>
  <Canvas.OpacityMask>
    <LinearGradientBrush EndPoint="0.5,0" StartPoint="0.5,1">
      <GradientStop Color="#99000000" Offset="0"/>
      <GradientStop Color="#00FFFFFF" Offset="1"/>
    </LinearGradientBrush>
  </Canvas.OpacityMask>
</Canvas>

無事に表示されました。

それにしても、この挙動はいったいバグなのが仕様なのか・・・。まぁ、 OpacityMask があるのでバグだとは思うのですが。
1.1 でこの現象がおこったのですが、たぶん 1.0 RC も同じ動きだとおもいます。リリースでは直ってることを期待。