1
votes

Can anyone explain what is going on with the BitmapIcon in WinRT? As I understand it, and the documentation is sparse, the BitmapIcon basically strips the color information out of an image and allows you to replace it with a Foreground color. However, if you create an image with white pixels and load it up in an BitmapIcon and set the foreground color to a "White" brush, it appears to corrupt the alpha values. My images use pure white pixels with the alpha used to provide rounding touches against a dark background. Here's what it looks like when loaded using an Image control:

enter image description here

Here's what the same PNG file looks like when loaded up using a BitmapIcon and setting the Foreground to "White":

enter image description here

The alpha information is completely lost. All the pixels are set to 0xFFFFFF regardless of the alpha value in the original image. Now here's where it gets a little strange. If I use a "Black" Foreground color, I get:

enter image description here

For some reason, the alpha shows up in some form on the darker images. Instead of taking the alpha literally from the original PNG image, there seems to be some function related to the foreground brush being applied. Can anyone give some insight into how the alpha component works (or doesn't work) on the BitmapIcon element?

1
Can you share your image file? - Filip Skakun
I wonder if it might have something to do with the premultiplied vs. non-premultiplied alpha pixel format in the file. Have you tried using an image with black icon pixels instead of white ones? - Filip Skakun
If you have a suggestion on how I can share the image file, I'd give it a try. As far as using black pixels, same effect as you see above. When the Foreground is set to White, all pixels that have alpha values show up as 0xFFFFFF. - Quarkly
Hmmm, no idea then. I'd try hitting msdn forums - maybe someone might help you there. - Filip Skakun
Do you have a vector graphic of that icon? You could use PathIcon instead. - Nate Diamond

1 Answers

0
votes

Same issue here with AppBarButton and a white/transparent image.

The following sentence from http://msdn.microsoft.com/en-us/library/windows/apps/windows.ui.xaml.controls.iconelement.foreground the first part of your post:

"Foreground replaces the color information from a BitmapIcon.UriSource source file. Any non-transparent pixel in the source image is replaced with the Foreground color."

I agree with you it's an annoying behaviour if you prepare the image correctly. And why it works for dark foreground colors I don't know.

Finally I wrote my own control:

public class Primitive3StateImagesButton : Button
{
    public static readonly DependencyProperty ImageSourceProperty = 
        DependencyProperty.Register("ImageSource",
        typeof (ImageSource), typeof (Primitive3StateImagesButton), 
        new PropertyMetadata(null));

    public static readonly DependencyProperty PointerOverImageSourceProperty =
        DependencyProperty.Register("PointerOverImageSource", typeof (ImageSource),
        typeof (Primitive3StateImagesButton), new PropertyMetadata(null));

    public static readonly DependencyProperty PressedImageSourceProperty =
        DependencyProperty.Register("PressedImageSource",
        typeof (ImageSource), typeof (Primitive3StateImagesButton), 
        new PropertyMetadata(null));

    public Primitive3StateImagesButton()
    {
        DefaultStyleKey = typeof (Primitive3StateImagesButton);
    }

    public ImageSource ImageSource
    {
        get { return ((ImageSource) (GetValue(ImageSourceProperty))); }
        set { SetValue(ImageSourceProperty, value); }
    }

    public ImageSource PointerOverImageSource
    {
        get { return ((ImageSource) (GetValue(PointerOverImageSourceProperty))); }
        set { SetValue(PointerOverImageSourceProperty, value); }
    }

    public ImageSource PressedImageSource
    {
        get { return ((ImageSource) (GetValue(PressedImageSourceProperty))); }
        set { SetValue(PressedImageSourceProperty, value); }
    }
}

With style:

  <Style TargetType="ctrls:Primitive3StateImagesButton">
    <Setter Property="Foreground" Value="{ThemeResource 
        AppBarItemForegroundThemeBrush}" />
    <Setter Property="VerticalAlignment" Value="Top" />
    <Setter Property="HorizontalAlignment" Value="Left" />
    <Setter Property="FontFamily" Value="{ThemeResource 
        ContentControlThemeFontFamily}" />
    <Setter Property="FontWeight" Value="Normal" />
    <Setter Property="Template">
      <Setter.Value>
        <ControlTemplate TargetType="ctrls:Primitive3StateImagesButton">
          <Grid Background="Transparent" x:Name="RootGrid">
            <VisualStateManager.VisualStateGroups>
              <VisualStateGroup x:Name="CommonStates">
                <VisualState x:Name="Normal" />
                <VisualState x:Name="PointerOver">
                  <Storyboard>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" 
                        Storyboard.TargetName="Ellipse">
                      <DiscreteObjectKeyFrame KeyTime="0"
                          Value="{ThemeResource 
                          AppBarItemPointerOverBackgroundThemeBrush}" />
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames 
                        Storyboard.TargetName="NormalImage"
                        Storyboard.TargetProperty="Visibility">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames 
                        Storyboard.TargetName="PointerOverImage"
                        Storyboard.TargetProperty="Visibility">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames 
                        Storyboard.TargetName="PressedImage"
                        Storyboard.TargetProperty="Visibility">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                    </ObjectAnimationUsingKeyFrames>
                  </Storyboard>
                </VisualState>
                <VisualState x:Name="Pressed">
                  <Storyboard>
                    <ObjectAnimationUsingKeyFrames 
                        Storyboard.TargetProperty="Stroke" 
                        Storyboard.TargetName="Ellipse">
                      <DiscreteObjectKeyFrame KeyTime="0" 
                          Value="{ThemeResource AppBarItemForegroundThemeBrush}" />
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames Storyboard.TargetProperty="Fill" 
                        Storyboard.TargetName="Ellipse">
                      <DiscreteObjectKeyFrame KeyTime="0" 
                          Value="{ThemeResource AppBarItemForegroundThemeBrush}" />
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames 
                        Storyboard.TargetName="NormalImage"
                        Storyboard.TargetProperty="Visibility">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames 
                        Storyboard.TargetName="PointerOverImage"
                        Storyboard.TargetProperty="Visibility">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                    </ObjectAnimationUsingKeyFrames>
                    <ObjectAnimationUsingKeyFrames 
                        Storyboard.TargetName="PressedImage"
                        Storyboard.TargetProperty="Visibility">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="Visible" />
                    </ObjectAnimationUsingKeyFrames>
                  </Storyboard>
                </VisualState>
                <VisualState x:Name="Disabled">
                  <Storyboard>
                    <ObjectAnimationUsingKeyFrames 
                        Storyboard.TargetName="RootGrid"
                        Storyboard.TargetProperty="Visibility">
                      <DiscreteObjectKeyFrame KeyTime="0" Value="Collapsed" />
                    </ObjectAnimationUsingKeyFrames>
                  </Storyboard>
                </VisualState>
              </VisualStateGroup>
              <VisualStateGroup x:Name="FocusStates">
                <VisualState x:Name="Focused">
                  <Storyboard>
                    <DoubleAnimation Duration="0" To="1" 
                        Storyboard.TargetProperty="Opacity"
                        Storyboard.TargetName="FocusVisualWhite" />
                    <DoubleAnimation Duration="0" To="1" 
                        Storyboard.TargetProperty="Opacity"
                        Storyboard.TargetName="FocusVisualBlack" />
                  </Storyboard>
                </VisualState>
                <VisualState x:Name="Unfocused" />
                <VisualState x:Name="PointerFocused" />
              </VisualStateGroup>
            </VisualStateManager.VisualStateGroups>
            <Grid
              Height="30"
              Width="30">
              <Ellipse
                x:Name="Ellipse"
                Fill="{ThemeResource AppBarItemBackgroundThemeBrush}"
                Stroke="{ThemeResource AppBarItemForegroundThemeBrush}"
                StrokeThickness="2"
                UseLayoutRounding="False" />
              <Image x:Name="NormalImage" Source="{TemplateBinding ImageSource}"
                  HorizontalAlignment="Center" VerticalAlignment="Center" 
                  Width="18" Height="18" Visibility="Visible" />
              <Image x:Name="PointerOverImage" 
                  Source="{TemplateBinding PointerOverImageSource}"
                  HorizontalAlignment="Center" VerticalAlignment="Center" 
                  Width="18" Height="18" Visibility="Collapsed" />
              <Image x:Name="PressedImage" 
                  Source="{TemplateBinding PressedImageSource}" 
                  HorizontalAlignment="Center" VerticalAlignment="Center" 
                  Width="18" Height="18" Visibility="Collapsed" />
            </Grid>
            <Rectangle x:Name="FocusVisualWhite" IsHitTestVisible="False" 
                Opacity="0" StrokeDashOffset="1.5" StrokeEndLineCap="Square" 
                Stroke="{ThemeResource FocusVisualWhiteStrokeThemeBrush}"
                StrokeDashArray="1,1" />
            <Rectangle x:Name="FocusVisualBlack" IsHitTestVisible="False" 
                Opacity="0" StrokeDashOffset="0.5" StrokeEndLineCap="Square" 
                Stroke="{ThemeResource FocusVisualBlackStrokeThemeBrush}"
                StrokeDashArray="1,1" />
          </Grid>
        </ControlTemplate>
      </Setter.Value>
    </Setter>
  </Style>