How to make some layer mask in Silverlight? - silverlight

I have an image object and a rectangle object. Now I want to be the image to be only visible where the rectangle is, everything else should have an opacity of 0.5 - the result should look something simliar to the following:
When I set the opacity of the rectangle to 0.5 the effect is the antipode - so how could I realize it as shown in the image? Size and position of the rectangle is changed by code-behind, but that shouldn't make any differences...
All hints / answeres appreciated :)

If you want to add an opaque mask to partially hide your image outside of a rectangle, it's rather easy.
<Grid>
<Image Source="myImage.jpg" Opacity="0.5/>
<Image Source="myImage.jpg" >
<Image.Clip>
<RectangleGeometry Rect="x,y,w,h"/>
</Image.Clip>
</Image>
</Grid>
Where x,y,w and h are your rectangle position and size (see MSDN). If you want to move the visible portion around, set the Clip property by code.
If you want to add the "black stroke effect", you could simply add a Rectangle with position and size matching those of your clipping path after the second image in your grid.
Do you want more infos?

Related

Translate a coordinate to maintain proportion when the canvas is resizing in WPF for VB.Net

I am making a Image manipulation tool in WPF (VB.Net)
I have implemented Image translation and zooming in Image control by using Image RenderTransform.
Actually, the Image is inside the Canvas control like a Photoshop Canvas.
And there is an Image within that Canvas control like a Layer in Photoshop.
What I want to do is when I resize the outer Canvas control, the Image inside should also be resized and repositioned as the outer control is.
It means, the Image should get 'new width, new height, new x(or offset-x or left), new y(or offset-y, or top)'
But so far as I know, surprisingly, RenderTransform does not actually change the Image location and size!
Which means, assume there is a photo of 10x20. If I enlarged the image twice then it looks like 20x40. But the properties of Width, ActualWidth, RenderedSize.Width all of them shows 10x20-the original size.
Moreover, although I pan(translate or relocate) the Image within the Canvas, the Left(or Canvas.Left) does not change at all!
In summary,
Image control within a Canvas control design
Move Image inside the Canvas with mouse - done by RenderTransform
Resize "Image(not Canvas)" inside the Canvas - performed by ScaleAtPrepend and RenderTransform too.
Resize the outer Canvas -> and it should encompasses the inside Image to be resized (like s to 1.5s in the figure) with the same
ratio of outer Canvas is, and the Left and Top (or offset x,y) of
the Image to be translated(or relocated) according to the proper
variable (like x,y to 1.5x,1.5y in the figure).
Unfortunately, using the zoom coefficient like '1.5' seems to be not viable because the original (x,y) point is alway (0,0) because the RenderTransform does not change the location values themselves.
Where can I start? How can I make it work?
Thank you in advance.
Here is a XAML design.
<Canvas x:Name="CanvasBoard" ClipToBounds="True" Background="#FFC1C1C1" >
<Image x:Name="CanvasImage" HorizontalAlignment="Left" VerticalAlignment="Top" MouseLeftButtonDown="MouseLeftButtonDown_Click" MouseMove="MouseMove_Click" MouseLeftButtonUp="MouseLeftButtonUp_Click" GotFocus="ImageGotFocus" />
</Canvas>
Panning with mouse core code.
Dim lsPoint = e.GetPosition(CanvasBorder)
Dim res As Point = lsPoint - firstPoint
Dim transform As MatrixTransform = CType(sender, Image).RenderTransform
Dim matrix = transform.Matrix
matrix.TranslatePrepend(res.X, res.Y)
CanvasImage.RenderTransform = New MatrixTransform(matrix)

WPF - Don't stretch image but fit it in a container (or MaxHeight)

I would like to display an image in WPF in its original size, which can be achieved by setting Stretch="None". However, if the image is bigger than its enclosing element, the image gets cropped, which is undesirable.
I would like the image to be downsized if it doesn't fit, but not stretched when it is smaller than its enclosing element. Is there a way to achieve this behaviour?
Set the Image control's StretchDirection property:
<Image Stretch="Uniform" StretchDirection="DownOnly" ... />

How can I anchor an ImageBrush to the bottom-left of an element?

I want to use an ImageBrush in a WPF element, and I want it to tile. But I want the image to line up with the bottom-left of the control, not the top-left. That is, instead of the top of the topmost tile being even with the top of the control, and a partial tile on the bottom end, I want it the other way around: the bottom of the bottom-most tile even with the bottom of the control, and a partial tile at the top. How can I do this?
Here's some XAML that repeats an image, but that anchors it to the control's top-left:
<Rectangle>
<Rectangle.Fill>
<ImageBrush ImageSource="C:\Temp\triangle.png"
Viewport="0 0 31 31"
ViewportUnits="Absolute"
TileMode="Tile"/>
</Rectangle.Fill>
</Rectangle>
Here's an illustration of what this does, and what I'm looking for (including what I want to happen as the element resizes):
(source: excastle.com)
How can I anchor the tiled images to the bottom of the element instead of the top (and make sure they stay anchored at the bottom, even as the element resizes)?
The 'easiest' way is by calculating a other Viewport coordinates.
If the image is 20x20: Viewport="0 11 31 31" I could be wrong by a couple of units.

How can I create an opacity mask in wpf that doesn't scale?

Ok, I've created a PNG-24 with transparency. It's basically a grayscale image that uses 'colors' in between black and transparent instead of black and white. I did this so I can use this as the Opacity Mask of a colored rectangle, thus rendering the image in whatever color I want using only a single graphic.
However, for the life of me, I can't get WPF to stop anti-aliasing the da*n image!!
I've set 'SnapesToDevicePixels' on the rectangle to which the brush is applied... I've set the ImageBrush's Scale to 'None'... I've set its ViewPort and the ViewBox to absolute units and sized them exactly to the source image. But no matter what I try, WPF still insists on trying to smooth things out! This is VERY frustrating!!!
So... anyone know how to use an image as an opacity mask but not lose the pixel-precise drawing that we have done? I just want WPF to render the damn thing as we drew it, period!
I have tried to reproduce your problem. Simply like this:
<Rectangle Width="200" Height="200" Fill="Red">
<Rectangle.OpacityMask>
<ImageBrush ImageSource="/mask.png"/>
</Rectangle.OpacityMask>
</Rectangle>
mask.png contains a simple diagonal mask, like that half of rectange is visible and other half is 100% transparent.
And recrangle is rendering pixel perfect (and aliased, as you want).
I think, that you may a DPI setting, that is not native to your monitor, and WPF just can`t render images correctly.
GOT IT! It's a layout issue that for some reason, there's no easy way to change. However, there's a value you can set called UseLayoutRounding that fixes it. I just set it at the root level (for this fauxample, a grid...)
<Grid UseLayoutRounding="True">
....
</Grid>
...and BAM! Works like a charm! "Sort of" like a 'SnapsToDevicePixels' but for positioning of elements (i.e. it rounds all layout-related values like left, width, etc. whereas SnapsToDevicePixels snaps the layout to the on-screen pixels when rendering.)
M

WPF: How do I create a background that repeats horizontally without scaling?

I would like to create a background for my window which is an image that I want repeated horizontally. So far I've tried with the ImageBrush, but this option repeats the image horizontally and vertically. Also, I don't want it to scale when user resize the window, as it makes the image look funny.
If what you want to do is tile an image horizontally as you would in CSS with the simple one liner "background-repeat: repeat-x" then after some (!) trial and error what you need in XAML is this:
<ImageBrush ImageSource="Images/my-background-image.png"
TileMode="FlipY"
Stretch="Uniform"
AlignmentY="Top"
Viewport="0,0,90,3000"
ViewportUnits="Absolute" />
Where the last 2 values on the Viewport attribute are the width of your image in pixels and then a very large number that is higher than your viewport height so that the image is not repeated in the Y direction within that height.

Resources