How to draw none fuzzy/blurry line in DrawingImage/DrawingContext? - wpf

See the image. I would like the middle line to be a crispy 1 pixel line.
You can copy and paste the sample markup into kaxaml .
alt text http://img832.imageshack.us/img832/1704/lines.png
<Page xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml">
<Image SnapsToDevicePixels="True" Stretch="None">
<Image.Source>
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Brush="Red" Thickness="1"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<LineGeometry StartPoint="0,0" EndPoint="50,0"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="1"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<LineGeometry StartPoint="0,5.860" EndPoint="50,5.860"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing>
<GeometryDrawing.Pen>
<Pen Brush="Black" Thickness="1"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<LineGeometry StartPoint="0,12" EndPoint="50,12"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
</Page>

I found the solution at:
http://msdn.microsoft.com/en-us/library/system.windows.media.renderoptions.setedgemode.aspx
<Image Stretch="None" RenderOptions.EdgeMode="Aliased">
RenderOptions.SetEdgeMode(this, EdgeMode.Aliased);

Change the middle line to:
<LineGeometry StartPoint="0,6" EndPoint="50,6"/>
You can get a crisp line on a pixel boundary by placing the line on a whole numbered unit.

I saw a similar issue with the Border control, although #phi your solution worked in most cases I also had to add the following to get it to completely work:
SnapsToDevicePixels="True"

Related

Wpf canvas grid with coordinates

I have following canvas Code:
<Canvas>
<Canvas.Background>
<DrawingBrush TileMode="Tile" Viewport="0,0,40,40"
ViewportUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,400,400"/>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="Red" Thickness="1"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
</Canvas.Background>
</Canvas>
This canvas generates a grid like you can find it on excel.Now I want to know if ist possible to generate the coordinates too. With cooridnates I mean that the first top row in the first fiels has a tiny text in it that says "A0" and the next one has "B0" and so every cell has coordinates like Excel.Would this be possible?

Draw special background

Is it possible in WPF to draw the background of a window the following way:
the background of the window is for instance white
vertical colored lines of 20 pixels width with a same-size gap in between, so that you get a red-striped pattern
horizontal colored lines of 20 pixels height in the same color, also with a same-size gap in between
the areas where the horizontal and vertical red lines overlap each other should be shown in white again, so that you get kind of a checkered pattern
I know how to draw lines in WPF and I know how to repeat a drawing to fill the whole background, but I don't know how the manage the part with the overlapping colors vanishing.
Not sure how large the gap is supposed to be. You may however adjust a DrawingBrush like this:
<Window.Background>
<DrawingBrush TileMode="Tile" ViewportUnits="Absolute" Viewport="0,0,100,100">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="White">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,100,100"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing
Geometry="M50,0 L50,40 M50,60 L50,100 M0,50 L40,50 M60,50 L100,50">
<GeometryDrawing.Pen>
<Pen Brush="Red" Thickness="20"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Window.Background>
Or with another TileMode:
<Window.Background>
<DrawingBrush TileMode="FlipXY" ViewportUnits="Absolute" Viewport="0,0,50,50">
<DrawingBrush.Drawing>
<DrawingGroup>
<GeometryDrawing Brush="White">
<GeometryDrawing.Geometry>
<RectangleGeometry Rect="0,0,50,50"/>
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Geometry="M0,45 L40,45 M45,0 L45,40">
<GeometryDrawing.Pen>
<Pen Brush="Red" Thickness="10"/>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingGroup>
</DrawingBrush.Drawing>
</DrawingBrush>
</Window.Background>

Fixing blurred lines that are drawn by DrawingBrush

This is my drawing brush:
<DrawingBrush x:Key="GridBrush" TileMode="Tile"
Viewport="0,0,60,30" ViewportUnits="Absolute"
Viewbox="0,0,60,30" ViewboxUnits="Absolute">
<DrawingBrush.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<GeometryGroup>
<LineGeometry EndPoint="0,30"/>
<LineGeometry EndPoint="60,0"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
<GeometryDrawing.Pen>
<Pen Brush="DarkGray" Thickness="1" DashCap="Flat" >
<Pen.DashStyle>
<DashStyle Dashes="2,2"/>
</Pen.DashStyle>
</Pen>
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingBrush.Drawing>
</DrawingBrush>
This is where I use it:
<Border Width="721" Background="{StaticResource GridBrush}" UseLayoutRounding="True" SnapsToDevicePixels="True" >
And the effects is:
Basically the middle line is "okish" the other two are wider then they should. I tried using UseLayoutRounding, SnapsToDevicePixels but with or without those options nothing changes. I ran out of ideas by now :/

XAML graphic vector as image source

Now many graphics designers provide the images as xaml file not ico, png, ..., How can I use a xaml file as image source?
Thanks
From the MSDN
<Image>
<Image.Source>
<DrawingImage PresentationOptions:Freeze="True">
<DrawingImage.Drawing>
<GeometryDrawing>
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry Center="50,50" RadiusX="45" RadiusY="20" />
<EllipseGeometry Center="50,50" RadiusX="20" RadiusY="45" />
</GeometryGroup>
</GeometryDrawing.Geometry>
<GeometryDrawing.Brush>
<LinearGradientBrush>
<GradientStop Offset="0.0" Color="Blue" />
<GradientStop Offset="1.0" Color="#CCCCFF" />
</LinearGradientBrush>
</GeometryDrawing.Brush>
<GeometryDrawing.Pen>
<Pen Thickness="10" Brush="Black" />
</GeometryDrawing.Pen>
</GeometryDrawing>
</DrawingImage.Drawing>
</DrawingImage>
</Image.Source>
</Image>
Instead of in-lining the GeometryDrawing you could refer to it as a static resource that you keep in a Resourcedictionary.
<Image>
<Image.Source>
<DrawingImage PresentationOptions:Freeze="True"
Drawing="{StaticResource myDrawing}">
</Image.Source>
</Image>
You will also find that you can show the drawing only once this way. So if you want this image to be present in the UI in multiple places, put the Image in a control template and style the controls with the template.
Thanks too all, this approach I know, my question was what happens when I have 100 xaml graphics files provided by a designer, now I have to extract the content from each file to move in a resource dictionary and set a key for each. I ask only if a more easy way as time.
Thank again too all.
I got a graphic like this
<Viewbox xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation" Width="128" Height="128">
<Canvas Width="10240" Height="10240">
<Path Data="M5986 6814l828 -828c124,-124 328,-124 452,0l2428 2428c124,124 124,328 0,452l-828 828c-124,124 -328,124 -452,0l-2428 -2428c-124,-124 -124,-328 0,-452z" Fill="#EDC87E"/>
<Path Data="M6082 5442l412 412 -640 640 -412 -412c-534,401 -1197,638 -1916,638 -1764,0 -3194,-1430 -3194,-3194 0,-1764 1430,-3194 3194,-3194 1764,0 3194,1430 3194,3194 0,719 -237,1382 -638,1916zm-2556 -4471c-1411,0 -2555,1144 -2555,2555 0,1411 1144,2555 2555,2555 1411,0 2555,-1144 2555,-2555 0,-1411 -1144,-2555 -2555,-2555z" Fill="#808080"/>
</Canvas>
</Viewbox>
This can be user very easy as a content to a Content control, but to youse this for a control which requires Image source I cannot I have to transform to:
<DrawingImage>
<DrawingImage.Drawing>
<DrawingGroup>
<DrawingGroup.Children>
<GeometryDrawing Geometry="M5986 6814l828 -828c124,-124 328,-124 452,0l2428 2428c124,124 124,328 0,452l-828 828c-124,124 -328,124 -452,0l-2428 -2428c-124,-124 -124,-328 0,-452z" Brush="#EDC87E">
<GeometryDrawing.Pen>
<Pen Thickness="1000" Brush="Blue"></Pen>
</GeometryDrawing.Pen>
</GeometryDrawing>
<GeometryDrawing Geometry="M6082 5442l412 412 -640 640 -412 -412c-534,401 -1197,638 -1916,638 -1764,0 -3194,-1430 -3194,-3194 0,-1764 1430,-3194 3194,-3194 1764,0 3194,1430 3194,3194 0,719 -237,1382 -638,1916zm-2556 -4471c-1411,0 -2555,1144 -2555,2555 0,1411 1144,2555 2555,2555 1411,0 2555,-1144 2555,-2555 0,-1411 -1144,-2555 -2555,-2555z" Brush="#808080"/>
</DrawingGroup.Children>
</DrawingGroup>
</DrawingImage.Drawing>
</DrawingImage>
The work in to trivial :(

WPF Drawing Paradox

How is it possible, that 2 ellipses with the same Radius where not (visually) with the same Radius?
in the image bellow, Black and Red ellipses has the same RadiusX... but look on the picture!
<GeometryDrawing Brush="Red">
<GeometryDrawing.Pen>
<Pen Brush="Yellow" Thickness="1"/>
</GeometryDrawing.Pen>
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry x:Name="MediumCircle"
Center="0,0" RadiusX="4" RadiusY="4" />
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
<GeometryDrawing Brush="Black">
<GeometryDrawing.Geometry>
<GeometryGroup>
<EllipseGeometry x:Name="SmallCircle"
Center="0,0" RadiusX="4" RadiusY="2"/>
</GeometryGroup>
</GeometryDrawing.Geometry>
</GeometryDrawing>
One has a stroked border and the other doesn't. You'll notice the radius lines up with the center of the stroked border.
Looks like the thickness is to blame. Make them the same for both.
I think I found the reply, but not sure... The Thickness of the ellipse goes not totally around the ellipse. If we Set the Thickness to 4 we will see only 2 pixels of ellipse, if we set at 8, we will not see the red circle anymore...

Resources