How to deactivate scaled image preliminary smoothing? - wpf

I've got a Grid with some scale transform applied; the Grid contains an image:
<Grid Background="Black">
<Grid.LayoutTransform>
<ScaleTransform ScaleX="5.7" ScaleY="3.7"/>
</Grid.LayoutTransform>
<Image Source="rw.bmp" VerticalAlignment="Top"/>
</Grid>
The image is 2 by 1 pixels, one pixel red and one white:
I expect to get such a rendered image (stretched):
but I actually get this one (again stretched):
You can see that the actual rendered image is somehow kind of smoothed before stretch, instead of being smoothed after stretch.
Is there a way to get the image as in the expected example?
Edit: tried different values of RenderOptions.BitmapScalingMode. The closest to what I need is "NearestNeighbor", which gives the following:

I'm not positive, but could you somehow use RenderOptions.BitmapScalingMode with this?

Related

Xaml, wpf image position and crop issue

I have images of 600px width and 600px height. we have three sizes of circles. all have the center in the middle. Some have reflection as shadow beneath it. I would like to crop the image for display purposes.
So the largest circle as shown above has a diameter of about 500 pixels, but the medium and small ones have less. I know in the code which size I have of object type Product. Because of the size differences I have to place them differently and used three placeholder images for it, like this:
<Image x:Name="imgCoinHolderSmall"
HorizontalAlignment="Center"
Margin="0,495,0,0"
VerticalAlignment="Top"
Stretch="Fill"
Width="200"
Height="200"/>
<Image x:Name="imgCoinHolderMedium"
HorizontalAlignment="Center"
Margin="0,510,0,0"
VerticalAlignment="Top"
Stretch="Fill"
Width="200"
Height="200"/>
<Image x:Name="imgCoinHolderLarge"
HorizontalAlignment="Center"
Margin="0,520,0,0"
VerticalAlignment="Top"
Stretch="Fill"
Width="200"
Height="200"/>
So can I change the properties of the image such that it does not display the red part of this screenshot:
By the way, I do not display the images on their original size (as you can see at the xaml code) I set the width to 200. It is just a display thing, I do not have to store the new image. I would like to do it on the fly, preferably by setting image properties in the xaml. (for all three sizes of circles)
Is using the CroppedBitmap the best approach? http://msdn.microsoft.com/en-us/library/ms752345.aspx it is for windows rt by the way.
One option would be to use a clipping mask:
<Image Source="MyImage.jpg">
<Image.Clip>
<RectangleGeometry Rect="10,10,80,80"></RectangleGeometry>
</Image.Clip>
</Image>
The rect structure takes X,Y, Width and Height values that you have to set depending on your image.

Adding a border to image control prevents image from displaying WPF

I have a perplexing problem that makes no sense to me - I am trying to place a border round an image control in WPF. The image control displays an image perfectly (I have loaded through code behind and XAML and both work fine). However when I place a border around the image control the image does not appear at all. This happening with three image controls all with identical config. Does anyone know why this is or how I can fix it? Many thanks, Jeff.
XAML (with border commented out) is below:
<!--<Border BorderBrush="Black" BorderThickness="2" Margin="201,172,618,450" Grid.Column="1">-->
<Image Name="imgFault11" Stretch="Fill" Grid.Column="1" Margin="200,172,619,450">
<!--</Border>-->
You are putting both in Grid.Column="1"
Put the image in the border
Start with no margins
<Border BorderBrush="Black" BorderThickness="2" Grid.Column="1">
<Image Name="imgFault11" Stretch="Fill">
</Border>
You may have to send the border to the Background. Once you add this it overlays the image. Right click the border .. go to order and then choose "Send to Back". The border control is in the toolbox. This is all a little messy though as getting the border to match the image box size takes time to get right and then you have one control on top of another..etc.

Animating from a point other than the left side

I have an animation problem that I'm not sure how to Google or find a solution for. I'm trying to basically create a wrapping Marquee. I do this by having the following within a canvas:
|---Section A---|---Section B---|Section C---|
The animation begins with the left side of section B on the right side of the screen, and ends when the right side of section B hits the left side of the screen. Sections A and C are a mirror image of Section B, which creates the "wrap around" effect. When the animation ends, I move everything to the right the exact width of Section B. To the user, nothing appears to have happened .. it's all just wrapping around.
The problem is this ... some of the items in the marquee can be hidden, or can change size. So if you hide an item, the item is hidden from all three sections. Since things are being hidden in Section A, and all the sections are sized dynamically, the entire marquee moves to the left.
Is there any way to "anchor" the animation at a spot, say, in the middle of Section B, so that when items are hidden in section A, it doesn't slide sections B and C over? Instead, I want Section A to move right to fill in the space.
Edit: Let me rephrase ... because this is confusing.
I have a canvas, which contains a stackpanel, which contains three more stack panels. These three stack panels are actually copies of the same information, which gives the illusion of a marquee that wraps around when I animate. When items are added/removed in the marquee, those items in the stack panel change, which adjusts the overall size of the stack panel, which adjusts the size of the canvas. What I'd like to know, is if I can "anchor" a specific location within the stackpanel. Can I "anchor" on the first item in the 2nd stackpanel copy?
To answer what APPEARS to be the primary question:
Is there a way to animation the position of a canvas using something
other than the Canvas.Left property
Set the RenderTransform property of the Canvas to a TranslateTransform and animate the TranslateTransform.X Property:
<Canvas x:Name="myCanvas" RenderTransformOrigin="0.5,0.5">
<Canvas.RenderTransform>
<TranslateTransform X="0"/>
</Canvas.RenderTransform>
</Canvas>
Then in code:
EDIT: The second parameter of this method call should be of type DoubleAnimation, not Duration. I must have been sleeping at my desk when I typed this. Sorry.
(TranslateTransform)MyCanvas.RenderTransform.BeginAnimation(TranslateTransform.XProperty, new Duration(TimeSpan.FromSeconds(3)));
I hope this helps.
My other answer is becoming obsolete as you elaborate on your desired behavior, so forgive me for posting a second. Based on my latter comments on the above answer, consider the following example:
<Canvas x:Name="LayoutRoot">
<Grid x:Name="MarqueePanels">
<Grid.ColumnDefinitions>
<ColumnDefinition/>
<ColumnDefinition/>
<ColumnDefinition/>
</Grid.ColumnDefinitions>
<Rectangle Grid.Column="0" Height="{Binding ElementName=PrimaryMarquee, Path=ActualHeight}" Width="{Binding ElementName=PrimaryMarquee, Path=ActualWidth}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=PrimaryMarquee}"/>
</Rectangle.Fill>
</Rectangle>
<StackPanel Grid.Column="1" x:Name="PrimaryMarquee">
<TextBlock Text="Marquee Item 1"/>
<TextBlock Text="Marquee Item 2"/>
<TextBlock Text="Marquee Item 3"/>
</StackPanel>
<Rectangle Grid.Column="2" Height="{Binding ElementName=PrimaryMarquee, Path=ActualHeight}" Width="{Binding ElementName=PrimaryMarquee, Path=ActualWidth}">
<Rectangle.Fill>
<VisualBrush Visual="{Binding ElementName=PrimaryMarquee}"/>
</Rectangle.Fill>
</Rectangle>
</Grid>
</Canvas>
As I mentioned above, setting the Visibility of any of the TextBox elements to Hidden will not cause the StackPanel parent to resize, however using Visibility.Collapsed WILL force an Arrange pass of the parent panel. So if you truly NEED to use a StackPanel to contain the visual elements, then I recommend based on your comments above using Visibility.Hidden in lieu of Visibility.Collapsed.
Also notice the use of VisualBrush to replicate the Marquee content. This will simplify the code, and ensure that all 3 visuals always match (with the exception of whatever positioning or transformation you apply to the Rectangle objects that house the VisualBrush).
Additionally, I should say that I personally would use a Canvas in lieu of the StackPanel, as the Canvas is much better suited for absolute positioning of child elements, hence the reason for your question.
Craig, I truly hope this helps. I (like most people on here) will try to help however I can. Good luck!
Got it.
I set the margin to -(theControl.ActualWidth / 2). All my code shifts everything back by that same amount to compensate.
Then I have an event handler for SizeChanged on the control, where I set this value. If the size of the control changes, the margin is update, and everything focuses on the middle of the control. If you have a specific point within the control that you want to center animation on, then use that point instead of the halfway point described above.

String Length in Pixels

How can I obtain the lenght of a string (given a font , size weight etc) in Pixels? I have seen recomendations to try System.Drawing.Graphics.* but that Assembly / Namespace doesn't seem to be available to me in silverlight.
I hope to center a text box under an image, but the text is provided dynamically.
Since your goal is to Centre the TextBox don't mess around with calculating width etc. Just tell the Container to centre the textbox.
eg.
<Grid>
<Image Source="ToolBox Avatar.png" Stretch="Fill"/>
<TextBlock HorizontalAlignment="Center" VerticalAlignment="Center" Text="TextBlock" TextWrapping="Wrap"/>
</Grid>
Thought I not familiar with developing for Silverlight, I think that this might be of use to you.

How to change x,y origin of canvas to bottom left and flip the y coordinates?

I have a bunch of data points that I would like to two-way bind to points on a canvas.
The points assume larger y values are reflected in an upwards direction like most math graphs.
How do I change the x,y origin of the canvas to the bottom left corner and reverse it's interpretation of the y coordinate?
(I would like to stay in XAML)
<Canvas>
<Canvas.LayoutTransform>
<ScaleTransform ScaleX="1" ScaleY="-1" CenterX=".5" CenterY=".5" />
</Canvas.LayoutTransform>
</Canvas>
I tried the ScaleTransform method extensively: It does not work. It only shifts one of the 2 coordinates, never both. This, however, works as advertised:
<Canvas Name="myCanvas" Width="0" Height="0" RenderTransform="1 0 0 -1 0 0"
HorizontalAlignment="Center" VerticalAlignment="Center" >
If you use databinding you can use a TypeConvertor, but for that you have to go outside the XAML and you need to know the size of the canvas beforehand.
I'd probably create a custom panel instead of using Canvas and give it the attached properties that make sense for your needs. Here is an example of implementing a custom panel:
http://blog.boschin.it/articles/silverlight-radialpanel.aspx
Something like Canvas is very simple since you don't have to do much in the measure and arrange overrides.
You may also be able to inherit from Canvas and override ArrangeOverride, I haven't tried that but it may work.

Resources