how to make MediaElement to take the whole space of a Grid? - c#

I have a MediaElement in a Grid , and i want it to take the entire space when i play it.
here is my code:
<Grid Grid.Row="2" Grid.ColumnSpan="2">
<Grid.Background>
<ImageBrush ImageSource="Resource/bgrdMedia.png" Stretch="None"/>
</Grid.Background>
<MediaElement x:Name="VideoControl" LoadedBehavior="Manual" UnloadedBehavior="Stop"
Stretch="Uniform" StretchDirection="DownOnly" MediaEnded="Element_MediaEnded"
HorizontalAlignment="Stretch"
VerticalAlignment="Stretch" />
</Grid>
but i have that:
any ideas! thanks !

By setting the StretchDirection to DownOnly you are preventing it from scaling upwards:
DownOnly | The content scales downward only when it is larger than the parent. If the content is smaller, no scaling upward is performed.
Source
If you leave the StretchDirection as Both (the default) and have the horizontal and vertical alignments as Stretch (which you have) it should give the result you want.
Note, however, that upscaling may result in a blurred or pixelated image if the original media isn't of sufficiently high resolution.

Related

Transform a colored image to a grayscale image using XAML?

Using XAML preferably,
I need to dynamically apply a gray-scale filter on a colored image from bottom to top. That's to say, i would like to be able to change the offset value of the gray-scale filter applied to my image pro grammatically.
For example, I would like to programmatically set 50% of the image in color (from the bottom of the image to its middle), and the other 50% of the image in gray-scale (e.g. from the middle of the image to its top).
I have read a lot of different answers, tried a lot of different things, and thought about a lot of different ways to do this.
I could have two images, one on top of the other. One would be in gray-scale and the other would be in color. I would then programmatically change the size of the gray-scale image so that the image in color below it would partially show and create a sort of half-half view to the user.
However, this solution poses an issue that I do not seem to be able to resolve. When changing the height value of the gray-scale image, the image automatically rescale itself due to the 'Stretch' property which is set to Uniform (and that I do not wish to change to None).
Another way to do this would be to programmatically change the color pixels of the image. I have had some success with this in the past, however, this is too slow for what I am trying to do here (ideally, I would be changing the colors of the image from gray-scale to the original color of the image selected by the user every 50 milliseconds until a certain height is reached).
A third method could be to apply an Opacity Mask on the image and use LinearGradientBrush to change the offset value to the desired position. This is the code I am currently using, it works but simply apply a gray color to the image without changing the original colors of the image to gray-scale (resulting in a sort of a washed out colored image):
XAML:
<Image x:Name="myImage" HorizontalAlignment="Left" VerticalAlignment="Top" Source="C:\Users\Clement\Desktop\test.png" Canvas.Left="159" Canvas.Top="81" Width="500" Height="375" >
<Image.OpacityMask>
<LinearGradientBrush EndPoint="0.5,0" MappingMode="RelativeToBoundingBox" StartPoint="0.5,1">
<GradientStop x:Name="myImageLinearGradientBrushStop" Color="Black"/>
<GradientStop Color="Transparent" Offset="1"/>
</LinearGradientBrush>
</Image.OpacityMask>
</Image>
Code-behind (in a timerEventProcessor that repeats itself every 50ms):
myImageLinearGradientBrushStop.Offset = percent * 0.01;
As mentioned previously, I have browsed a lot of different websites, read a lot of similar questions and tried a lot of different answers and still cant satisfactorily solve the problem.
The XAML below uses a Grid with two rows to display two Images on top of each other. The Width and Heigh of the top Image are bound to the size of the bottom Image, which spans both Grid rows. An inner Grid is used to clip the top Image.
<Grid>
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image x:Name="image" Grid.RowSpan="2" Source="..."/>
<Grid>
<Image Width="{Binding ActualWidth, ElementName=image}"
Height="{Binding ActualHeight, ElementName=image}"
HorizontalAlignment="Center" VerticalAlignment="Top">
<Image.Source>
<FormatConvertedBitmap Source="{Binding Source, ElementName=image}"
DestinationFormat="Gray8"/>
</Image.Source>
</Image>
</Grid>
</Grid>
Thanks to Clemens' help, I was able to get a solution to my problem!
This is the final XAML code for those whom might be interested:
<Grid Width="500" Height="375">
<Grid.RowDefinitions>
<RowDefinition/>
<RowDefinition/>
</Grid.RowDefinitions>
<Image x:Name="image" Grid.RowSpan="2" Source="C:\Users\Clement\Desktop\test_image.png" />
<Grid Margin="0,0,0,166" Grid.RowSpan="2">
<Image Width="{Binding ActualWidth, ElementName=image}"
Height="{Binding ActualHeight, ElementName=image}"
HorizontalAlignment="Center" VerticalAlignment="Top">
<Image.Source>
<FormatConvertedBitmap Source="{Binding Source, ElementName=image}"
DestinationFormat="Gray8"/>
</Image.Source>
<Image.OpacityMask>
<ImageBrush ImageSource="C:\Users\Clement\Desktop\test_image.png"/>
</Image.OpacityMask>
</Image>
</Grid>
</Grid>
Here I simply added the OpacityMask to the Gray8 image to bring back its transparency.
Happy coding!

Display image using a scaling value on wpf MVVM

I have this markup in XAML:
<Canvas Width="250" Height="250">
<Image Source="{Binding UserImage}" HorizontalAlignment="Center" VerticalAlignment="Center" />
</Canvas>
This is showing image with its original size (I don't know the size as it depend on userimage which is not available at design time)
I want to show it in say 1/10 of its original size. It is very important that the pixel size of the display image be exactly 1/10 of original image size.
How can I do this?
This is an MVVM application, and I prefer to do this in XAML instead of C# code if it is possible.
Have you tried applying a scale transformation on the image? First, add the following to the Image control to enforce it being drawn in its original size:
<Image ... Stretch="None" />
Then apply a LayoutTransformation to scale the image down to 1/10 of the original size:
<Image Stretch="None" Source="{Binding UserImage}" HorizontalAlignment="Center" VerticalAlignment="Center">
<Image.LayoutTransform>
<ScaleTransform ScaleX="0.1" ScaleY="0.1"/>
</Image.LayoutTransform>
</Image>
I would have just put this in a comment, but I don't have enough rep. Can you not just set the height and width on the <Image> tag instead of the <canvas> tag? or possibly use the MaxHeight and MaxWidth Property on the <Image> tag?

how to avoid a single pixel line disappear in wpf?

I use a Path element(StrokeThickness="1" SnapsToDevicePixels="True")
in Grid. I want to resize the window, the Grid element is wrapped by a Viewbox element.
Problem
When I resize the window, the Path will disappear some time. If I turn SnapsToDevicePixels to false, the Path element may blur which is not what I want.
How to avoid a single pixel line dispear?
the XAML code:
<Window x:Class="WpfApplication2.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="207" Width="475">
<Viewbox Stretch="Fill">
<Grid Height="320" Width="517">
<Path Data="M0,0 H1 z" StrokeThickness="1" Stroke="Black" Margin="72,73,79,218" Stretch="Fill" SnapsToDevicePixels="True" MinHeight="1"/>
</Grid>
</Viewbox>
Pity for I have no reputation to post the runtime effect.
I have experimented the same problem with separators put in a Viewbox. Some of these disappear for some resolutions. To fix it, I replace them with border with 1 pixel height :
< Border Background="DarkGray" Grid.Row="0" Grid.ColumnSpan="7" Height="1" />
This avoid single line of one pixel to disappear in viewBox.
Hope it could be useful for you too.

SurfaceInkCanvas scales strokes when painting out of bounds

I have a ScatterView that contains an image over which I should be able to draw.
<s:ScatterView HorizontalAlignment="Center" Margin="0,0,0,0" Name="desk" VerticalAlignment="Center">
<s:ScatterViewItem Width="200" Height="200">
<Grid>
<Image Name="img1" Source="/Resources/Desert.jpg"/>
<Viewbox>
<s:SurfaceInkCanvas Name="cvs1"/>
</Viewbox>
</Grid>
</s:ScatterViewItem>
</s:ScatterView>
I noticed that whenever I draw an ink trail towards the border of the image, the strokes on the ink canvas are scaled down to make room for more stuff. I do not want these strokes to be zoomed out. How can I change this behavior?
Here is a video that shows what's going on.
I figured it out. This behavior is caused by the fact that I hadn't defined a Width and Height on the SurfaceInkCanvas. This should do the trick:
<s:SurfaceInkCanvas Name="cvs1" Width="200" Height="200" />

Resizing inkcanvas to the left and top

I want to resize width and height of inkcanvas to fit the screen. When I resized it, the width expands to the right and height expands to the bottom. But inkcanvas is not fit to screen.
I also want to fix the position of inkcanvas child element. If I can resize inkcanvas to fit the screen, the position of inkcanvas child element will not change.
How do I resize inkcanvas to the left and top to fit the screen?
<Canvas x:Name="Screen" >
<InkCanvas Name="inkcanvas" ResizeEnabled="True"
Width="{Binding ElementName=LayoutRoot, Path=ActualWidth}"
Height="{Binding ElementName=LayoutRoot, Path=ActualHeight}"
EditingMode="Select" ClipToBounds="False"
Background="Bisque"
SelectionChanging="OnSelectionChanging"
Visibility="Collapsed" HorizontalAlignment="Stretch" VerticalAlignment="Stretch">
<!-- InkCanvas' Child Elements -->
</InkCanvas>
<Canvas.RenderTransform>
<MatrixTransform/>
</Canvas.RenderTransform>
</Canvas>
Thanks
Update:
I put inkcanvas in a grid. It fit to the screen but the position of child element is changed.
I want to fix the red rectangle position.
The position of red rectangle should not be changed.
<Grid>
<InkCanvas x:Name="inkcanvas" Background="Transparent">
<Rectangle Height="41" HorizontalAlignment="Left" Name="rectangle1" Stroke="Black" VerticalAlignment="Top" Width="69" Fill="#FFDB1111" />
</InkCanvas>
</Grid>
My big picure:
My WPF Application contain many pictures. I can zoom in/out the canvas. I can select the pictures by using selection tool.
I have canvas and inkcanvas.
canvas: contain picture and zoom in/out
inkcanvas: has selection tool
If I zoom out, the canvas and inkcanvas become smaller.
If I use selection tool, I copy all pictures from canvas to inkcanvas.
But the inkcanvas is zoom out, I cannot use selection tool if outside the inkcanvas boundary.
It is the reason why I want to resize inkcanvas and fix the children position.
<Window x:Class="WpfInkCavasSaveImage.MainWindow"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
Title="MainWindow" Height="1091" Width="873" WindowState="Maximized">
<Grid Margin="0,0,0,10" >
<Grid.RowDefinitions>
<RowDefinition Height="1200*" />
<RowDefinition Height="50" />
</Grid.RowDefinitions>
<InkCanvas HorizontalAlignment="Stretch" Margin="1,1,1,10" x:Name="inkCanvas1" VerticalAlignment="Stretch" Width="Auto" RenderTransformOrigin="0.5,0.5" Background="LightGreen" SnapsToDevicePixels="True" IsManipulationEnabled ="True" Grid.RowSpan="2">
<InkCanvas.CacheMode>
<BitmapCache/>
</InkCanvas.CacheMode>
<InkCanvas.DefaultDrawingAttributes>
<DrawingAttributes Color="Black" FitToCurve="True" Height="2.0031496062992127" IgnorePressure="False" IsHighlighter="False" StylusTip="Ellipse" StylusTipTransform="Identity" Width="2.0031496062992127"/>
</InkCanvas.DefaultDrawingAttributes>
</InkCanvas>
</Grid>
</Window>
public partial class MainWindow : Window
{
public MainWindow()
{
InitializeComponent();
inkCanvas1.Width = System.Windows.SystemParameters.WorkArea.Width;
inkCanvas1.Height = System.Windows.SystemParameters.WorkArea.Height;
}
}
This depends on the container around the InkCanvas. Further you cannot expect the child-elements not to move if you mess with their container. If you need the child elements to behave independently of the InkCanvas you might want to rethink if that is a good idea and if what you want to accomplish can not be done more efficiently using another setup.
You should tell us more about what the big picture is of what you want to achieve, the fact that children are affected by manipulations of their container is expected and generally wanted. Maybe there is a better approach than to try and scale the container and at the same time having to shift all children around to nullify such a manipulation.
Remove all the margins from the inkcanvas and put it in a Grid.
Could you explain why this would not work for you?
<Grid>
<InkCanvas>
...
</InkCanvas>
</Grid>
Edit There are two way to keep the child element where it is:
As soon as the position or the size of the InkCanvas changes adjust the child positions accordingly. this means that you have to pick a fixed position (window topleft, screen topleft, ...) that determines the actual position of the child.
Remove the child from the InkCanvas and put it in the correct container (the one that determines the child's position.
I would prefer #2 as is is more logical and requires less calculations/event-handling

Categories

Resources