I want to use custom brushes with the InkCanvas.
Their is a code snippet from MSDN. (http://msdn.microsoft.com/en-us/library/ms747347.aspx)
If i use that code and move my mouse VERY fast i get space between the brushes(ellipses):
And my question is of course how to fix this but I'm also curious why this is happening (I want to learn from it) I thought maybe i did something wrong but even if i cut/paste the example it's happening.
One little thing i noticed when reading the code was this comment in the CustomStroke class
// Draw linear gradient ellipses between
// all the StylusPoints in the Stroke
Seems to me like it should draw ellipses between the points not only at the points.
I'm using C#.NET.
Again in short:
Why is this happening
Help me fix it :)
Why this is happening
The custom InkCanvas in the example draws an ellipse at every collected StrokePoint but makes no attempt to draw lines between them. The standard InkCanvas control is implemented by drawing lines between the points it is given. This is why the custom InkCanvas implementation from the example leaves gaps and the built-in one doesn't.
How to "fix" it
The custom code could easily be extended to not leave gaps: In addition to drawing ellipses at each point, it could draw lines between each pair of points.
Code to draw connecting lines might be added before the code to draw the ellipses, like this:
// Draw connecting lines
var geo = new StreamGeometry();
using(geoContext = geo.Open())
{
geoContext.StartFigure(stylusPoints[0], false, false);
geoContext.PolyLineTo(stylusPoints.Skip(1).Cast<Point>(), true, false);
}
drawingContext.DrawGeometry(null, connectingLinePen, geo);
// Draw ellipses
for(int i = 1; i < stylusPoints.Count; i++)
{
... etc ...
This code works by constructing a polyline StreamGeometry and then drawing it to the context. Using a StreamGeometry in this context is generally more efficient than creating a PathGeometry with a Polyline or doing a bunch of DrawLine calls directly on the drawingCanvas.
Note: Using a better digitizer won't solve the underlying problem, which is that the custom InkCanvas is actually designed to only show data at the sampled points and not in between.
ReDAeR
Look this
http://msdn.microsoft.com/en-us/library/bb531278.aspx
Why this is happening: The WPF InkCanvas control has a limited number of inputs per second when using a mouse; meaning that your stylus inputs will have greater and greater distances between them as you move the mouse faster and faster. The sample itself appears to draw elipses at every stylus input point, not in-between the points.
How to solve this: use a Tablet PC - a digitizer such as on a Tablet PC has a much higher number of inputs per second so it is more difficult to encounter, or fill in the blanks - essentially estimate based on previous points, perhaps a bezier curve.
Related
I have no experience with images. I have to detect simple object in static image. For example I have image like:
I want to detect edges and remove background. Just to compare them.
Something like this.
Do u have any solutions of this problem? Images have often white backgrounds.
I've just thought about detect edges, and take everything what they contains.
To segment out the shoe-
Anadptive Threshold to remove the smooth changing background.
Sobelx, which removes the apparent background line, which i assume is
common for images of this setup.
dilate, closing operation to separate out the shoe.
Find contours, bounding box etc as per your choice.
Do an additional threshold if you want to remove the shadow at the bottom.
I am currently writing a program where I need to draw some graph's. I need to have a little bit specific layout in these graphs. For example I have three stages of a length in days defined by the user. a start stage of for example 30 days, a mid stage of 40 and an end stage of 20 days. These stages I want to have all a different backgroundcolor in the graph. I do that by drawing pictureboxes and adapting their widths to the stage lengths. Also for every day in the total length I want to draw a vertical line and for the amount of horizontal lines in the graph I take the maximum of y = f(x).
y = f(x) needs to be plotted on the graph. For I use many pictureboxes on the background I cannot use the graphics.DrawLine for it will be drawn behind the pictureboxes. So I decided to make the line with an array of pictureboxes ;) It works fine, but obviously it takes a lot of time to load the program now.
Is there another way to draw this graph using arrays of controls that require less effort from the computer? Or should I completely stop with the arrays?
(I wanted to post my picture here, but I don't have ten reputation yet because I'm a noobie :( )
Later on I will add more lines to this graph, but since I figured that my program is already slowing down I ceased programming those other lines and went to the all-knowing forum!
Any help will be much appreciated!
Greetz,
Arrie
The common form controls aren't really suitable for this purpose. I'd suggest taking a look at using libraries that give you more power and control over visuals and graphics.
#Kári is right:
If you want to stay with .NET only (no 3rd library dependence) you can use GDI. In .NET you can use by including System.Drawing.dll as an reference.
One simple yet correct approach would be:
create a target control (picturebox for example)
implement the OnPaintDraw Event which gives you an Graphics object
that contains many drawing methods. See MSDN for more information:
MSDN -> Graphics
The methods of Graphics will always draw above the control, so make sure your target control is visible an not behind any other control.
If GDI is not enough you can check out other libraries. (See .NET graph library around?)
- Building a CAD program in WPF:
I want to build a CAD program that will have 10000 LINE objects at a time. I'm using LineGeomery class for drawing lines that are added to a Canvas. I have implemented Zoom and Pan and the performance is great so far.
Only one major disappointment:
The Thickness of the lines gets scaled while zooming. I have tried to Bind the Thickness property of the lines to a factor to keep them unchanged, This works but reduces the performance dramatically while zooming. Clearing and drawing new lines with new thickness on MouseWheel is out of the question as well. This one too reduces performance and is not practical in the current method.
- Now what solutions I have?
Stick with the current method and ignore the change in Thickness
Do the whole job in GDI+
Host GDI in WPF
Use WPF Viewport3D (Will the LineThickness be invariant there?)
- Other solutions?
What other paths you would take. I'm new to WPF and programming and I'm eager to learn.
UPDATE:
This is the way I'm doing it right now. I draw 3000 Lines on the Visual Layer using Pen an Brushes. Then on MouseWheel event I redraw all the Lines with the updated Thickness. Also I don't show the rest of the Lines to the user until he zooms so I only create 3000 out of 10000 Lines in each MouseWheel event.
Instead of using Line objects, you could draw your lines by Path objects. Here is an answer https://stackoverflow.com/a/15323221/1305119
Next to hosting a winforms element inside WPF, I would also implement partial rendering on the zooming feature, e.g. when you zoom in everything that is not visible should not be calculated as well!
There's a neat little library called YLScsDrawing that allows you to skew a bitmap between four corners, and then draw it. Unfortunately, whenever I attempt this, my rectangular bitmap always has incredibly aliased edges, even with IsBilinearInterpolation = True. How could I go about changing this library so that it antialiases the edges?
An example of what I mean can be found below. Look at the top of the green line.
Background
I want to be able to get the drawn dimensions of a zoomed image inside the picturebox (I'll explain below).
The PictureBox.ImageRectangle property seems to be exactly what I'm looking for because it shows the height and width of the resized image, as well as it's relative top, left position inside the control.
The trouble is PictureBox.ImageRectangle is private and so I can't read the values without using reflection (which is obviously not ideal).
Actual Question
My question is, is there another way that I can easily get to these values without writing a method to calculate what the values "ought" to be? I can do that easily enough, but I feel I'd be reinventing the wheel.
Context:
I'm writing a simple image processing app in C# and one of the things it has to do is allow the user to draw a selection around a portion of the image (a lot like the Marquee tool in Photoshop).
I need to know the dimensions of the rendered image so I know where to set the bounds of my marquee tool and also to translate the values of the drawn rectangle to points on the scaled bitmap inside the control.
My answer look simple so maybe I'm missing something, but I think Control.DisplayRectangle suits your need.
EDIT
OK, missed the point; however see How to get the value of non- public members of picturebox?
if you want to access dimension of the image in picture box you can use
GraphicsUnit units = GraphicsUnit.Point;
RectangleF imgRectangleF = pictureBox1.Image.GetBounds(ref units);
Rectangle imgRectangle = Rectangle.Round(imgRectangleF);