Combining two semi-transparent ellipses - c#

Have a strange one. I have two ellipses that have an opacity of 0.7. What I'd like to do, is where the two ellipses cross, show a different color. In an old WF image I'd have run through each pixel and swapped colours, but I'm not sure how to do this with a layer in Silverlight. Anyone have any ideas?
Thanks!

edit: Sorry, there were a few errors with the properties of the various elements. This is tested:
Create a Path and put as Path.Data a GeometryGroup that has the two EllipseGeometries as child elements. Set GeometryGroup.FillRule to "EvenOdd" so that the area that both ellipses cover is not filled, and set "Fill" to the color you want the ellipses to have (here: AliceBlue).
Put that Path into a Control with "Background" property, like Border, and set that Background to the color you want the area both ellipses are covering to be (here: yellow).
Then you set Clip to the same GeometryGroup with FillRule set to "Nonzero" to prevent the area around the ellipses to also be painted with the background color.
<Border Background="Yellow">
<Path Fill="AliceBlue" Stroke="Black" StrokeThickness="4">
<Path.Data>
<GeometryGroup FillRule="EvenOdd">
<EllipseGeometry Center="100,100" RadiusX="40" RadiusY="80" />
<EllipseGeometry Center="100,100" RadiusX="80" RadiusY="40" />
</GeometryGroup>
</Path.Data>
</Path>
<Border.Clip>
<GeometryGroup FillRule="Nonzero">
<EllipseGeometry Center="100,100" RadiusX="40" RadiusY="80" />
<EllipseGeometry Center="100,100" RadiusX="80" RadiusY="40" />
</GeometryGroup>
</Border.Clip>
</Border>
If you need both ellipses to be painted in different colors use two Border and Path objects, use the same GeometryGroup with "EvenOdd" and set each of Border.Clip to one EllipseGeometry object.
If you need a more detailed definition use a PathGeometry instead of GeometryGroup and define the area with ArcSegments.

Related

DrawingImage is getting fuzzy and image gets bigger and cut-off when Windows scaling is set to more than 100%, for example 125%

I have an WPF usercontrol which is used in a winforms applications. WPF usercontrol is contained within an ElementHost container.
This WPF usercontrol has some images, button with images, labels, etc.
I have a dictionary with some geometries, the following is one of them.
<Geometry x:Key="hlpGeometry">F0 M22,22z M0,0z M11,22C17.0751,22 22,17.0751 22,11 22,4.92487 17.0751,0 11,0 4.92487,0 0,4.92487 0,11 0,17.0751 4.92487,22 11,22z M12.1901,16.6889L10.2662,16.6889 10.2662,18.6998 12.1901,18.6998 12.1901,16.6889z M8.18758,5.59005C7.40125,6.43439,7.00808,7.55265,7.00808,8.94484L8.72898,8.94484C8.76121,8.10695 8.89334,7.46564 9.12537,7.02091 9.53787,6.2217 10.2823,5.82209 11.3587,5.82209 12.2288,5.82209 12.8508,6.05412 13.2246,6.51818 13.6049,6.98224 13.795,7.53009 13.795,8.16173 13.795,8.61291 13.6661,9.04797 13.4083,9.46691 13.2665,9.70539 13.0796,9.9342 12.8475,10.1533L12.0741,10.9171C11.3329,11.6454 10.8527,12.2932 10.6336,12.8604 10.4144,13.4211 10.3049,14.1623 10.3049,15.084L12.0258,15.084C12.0258,14.2719 12.116,13.6596 12.2965,13.2471 12.4834,12.8281 12.8862,12.319 13.505,11.7195 14.3557,10.8945 14.9197,10.2694 15.1969,9.84396 15.4804,9.41857 15.6222,8.86427 15.6222,8.18107 15.6222,7.05314 15.2387,6.12824 14.4718,5.40636 13.7112,4.67804 12.6961,4.31388 11.4263,4.31388 10.0535,4.31388 8.9739,4.73927 8.18758,5.59005z</Geometry>
<DrawingGroup x:Key="hlpDrawingGroup" ClipGeometry="M0,0 V22 H22 V0 H0 Z">
<GeometryDrawing Brush="#FF00AA2B" Geometry="{StaticResource hlpGeometry}" />
</DrawingGroup>
<DrawingImage x:Key="ico_helpDrawingImage" Drawing="{StaticResource hlpDrawingGroup}" />
I have an WPF Image and I bound above DrawingImage to it using the Source attribute. I bind the source attribute to a property in the view model.
Something like below:
<Image x:Name="MyImage"
Height="24"
Width="24"
VerticalAlignment="Center"
Source="{Binding Path=MyIcon}"/>
It is working fine when windows is scaled to 100% but when scaled to a higher one, let's say, 125%, then the image gets fuzzy.
Also the image look like gets bigger than 24x24 and it is being cut-off when I set a scale greater than 100% (125%).
How can I make image to not get fuzzy and set image to always be the same size 24x24?
You can use the UseLayoutRounding and SnapsToDevicePixels properties.
Set the UseLayoutRounding property to true to prevent blurring caused by anti-aliasing and to tell the layout system to align elements with pixel boundaries.
RenderOptions.BitmapScalingMode is mainly for larger images to be displayed more smoothly, you can choose HighQuality.
Use high quality bitmap scaling, which is slower than LowQuality mode, but produces higher quality output.
You can check this link:
https://learn.microsoft.com/en-us/dotnet/api/system.windows.media.bitmapscalingmode?redirectedfrom=MSDN&view=windowsdesktop-7.0
Codeļ¼š
<Image x:Name="img" MouseWheel="img_MouseWheel"
Height="24"
Width="24"
UseLayoutRounding="True"
SnapsToDevicePixels="True"
VerticalAlignment="Center"
RenderOptions.BitmapScalingMode="HighQuality"
Source="2.jpg"/>
With images I have always found the below to always clear up the fuzzy stuff.
<Image x:Name="MyImage"
Height="24"
Width="24"
RenderOptions.BitmapScalingMode="HighQuality"
VerticalAlignment="Center"
Source="{Binding Path=MyIcon}"/>

Draw a stretchable round bracket in WPF

I'm trying to draw a round bracket in WPF. I'm working a Math Editor, so I'll need the bracket to be able to stretch in height as required.
Since most of my stretch text research have failed I've decided to get this accomplished by drawing an arcsegement within my user control, And update it's height each time the UserControl changes in height.
But then there's just one problem, I need each part of my bracket to be in the right thickness (I'm a little bit of a perfectionist). Like a perfect bracket.
Notice some parts of the bracket are thicker than others (especially the middle), Is there a way something like that can be accomplished using arcsegment or do I have to put a normal bracket in a Viewbox, stretch it and experiment till I'm satisfied (rather not though).
Any tips/ideas would be awesome:)
Use 2 ArcSegment to form a PathFigure. Here is a tutorial of combining Arc segments.
<Path Stroke="Black" Fill="Black">
<Path.Data>
<PathGeometry>
<PathGeometry.Figures>
<PathFigure StartPoint="100,30" IsClosed="True">
<ArcSegment Point="100,130" Size="150 150" />
<ArcSegment Point="100,30" Size="100 100" SweepDirection="Clockwise" />
</PathFigure>
</PathGeometry.Figures>
</PathGeometry>
</Path.Data>
</Path>

Tint a partially transparent image in WPF

How can I tint/colorize an image in WPF (using MVVM) without sacrificing performance? A purely XAML solution would be ideal, as modifying bitmaps in the code will cause performance loss with lots of changing images. The image is made up of more than simple shapes, so it is not possible using a path.
Unlike WinForms/GDI+, WPF does not seem to contain any easy ways to colorize/tint an image as it is being rendered. Two ideas for accomplishing this are, using a shader, or overlaying a colored rectangle over the image.
I decided to try the rectangle route and found that it works. Basically, all you need to do is overlay a colored rectangle over your image, and use an OpacityMask to restrict the color fill to a certain area. OpacityMask is primarily used with paths, but it can take any kind of brush, including an ImageBrush. This means you can use your image as a "stencil" for the colored fill.
Example: (Taken from my application where a user can "highlight" a section of a map, the actual image looks like this)
Before Overlay & Mask
After Overlay & Mask
Here is all of the required XAML for this:
<Image
Source="{Binding MyImage}"
Width="150"
Height="150" />
<Rectangle Width="150" Height="150">
<Rectangle.Fill>
<SolidColorBrush Color="{Binding Color}"/>
</Rectangle.Fill>
<Rectangle.OpacityMask>
<ImageBrush ImageSource="{Binding MyImage}"/>
</Rectangle.OpacityMask>
</Rectangle>
To bind the color to a brush as I did, use a ColorToBrushConverter.

C# Drawing: What is the best way to draw a polygon with a hole in the middle

I have a shape that is defined by an outer border and then an inner border. IF there is no inner boarder, the shape is solid. If there is an inner border I want the polygon/path to be defined only between the two borders; I don't want to draw the outside and then draw the inside in the background color.
For example, if I have a square defined by the following coordinates for the outside border:
{0,0}, {20, 0}, {20,20}, {0, 20}
Then that square which is 20x20 with its bottom left right corner on the origin. That shape then has a triangle cut out of the center:
{10,10}, {15,10}, {15,15}
How can I create a path that contains this shape using either WPF or GDI+?
You can draw that shape with XAML: (The key is to use a CombinedGeometry with GeometryCombineMode="Exclude")
<Path Fill="Black">
<Path.Data>
<CombinedGeometry GeometryCombineMode="Exclude">
<CombinedGeometry.Geometry1>
<RectangleGeometry Rect="0,0,20,20"/>
</CombinedGeometry.Geometry1>
<CombinedGeometry.Geometry2>
<PathGeometry>
<PathFigure StartPoint="10,10">
<LineSegment Point="15,10"/>
<LineSegment Point="15,15"/>
</PathFigure>
</PathGeometry>
</CombinedGeometry.Geometry2>
</CombinedGeometry>
</Path.Data>
</Path>
In GDI+, you can use FillPath() or DrawPath() with FillModeAlternate.
There's an example pretty close to what you're asking for here.
Just draw the holes on top of the main contour using the background color. It will look as if they were real holes
edit
use this approach if the api you are using does not support holes. Which is why I assume you are asking

Issues with getting some text centered in a Polygon

I'm creating a map in Silverlight that contains a bunch of rooms. All of the rooms are polygons, most of them are rectangles.
So what I'm doing is creating a Polygon using the x y point coordinates for the room. Something like
Polygon p = new Polygon
p.points = pointCollection;
MainCanvas.Chilren.Add(p);
This works great. Next, I want to put the name of each room inside these on the map. I figured I'd just add a textblock child to the polygon. Unfortunately, it seems that UIElements cannot contain child UIElements. I think this is dumb, but whatever.
Next plan: Create a new Silverlight user control containing the polygon and a text field. Center text field in polygon within user control. So I just create one of these UserControls "Room" set the property "RoomShape" to the polygon and add it to the canvas. The problem here is that The Usercontrol is always added at position (0,0) and the room shape is in the bottom right position. What I really wanted was for the control to take on the size and shape of the polygon I add to it so I can find the center and add the text in. Is this possible?
Also, let's say I add a polygon to my layout in a control:
LayoutRoot.Children.Add(poly);
Why do
poly.ActualHeight
poly.ActualWidth
poly.height
poly.width
all return 0 or NaN when I can clearly see them on the Canvas?
And why do
Canvas.GetTop(poly);
Canvas.GetLeft(poly);
both return 0 when I can clearly see they are not located at (0,0)?
Any other suggestions for centering text in a polygon is appreciated.
First of all, for sure you cannot add UIElements to Polygon. The Polygon is not a container so you can't add elements in it.
Second, if you want to set text in the middle of your polygon, why don't you wrap your polygon in a Grid. Then in the Grid, add your polygon, and your textblock like that :
<Grid x:Name="room1" Background="LightBlue" HorizontalAlignment="Center" VerticalAlignment="Center">
<Polygon Stroke="Black" Fill="Beige">
<Polygon.Points >
<Point X="0" Y="0" />
<Point X="20" Y="100" />
<Point X="100" Y="50" />
<Point X="0" Y="0" />
</Polygon.Points>
</Polygon>
<TextBlock VerticalAlignment="Center" HorizontalAlignment="Center">Room Name</TextBlock>
</Grid>
Third, for the size always at 0, this is probably because you create/add the usercontrol at Load time. I know its sad but you will have to do the work in the UserControl_SizeChanged event of the container.

Categories