Is it possible to change PowerPacks.LineShape
smoothingMode?
I tried to use this code(a class that inherits LineShape
):
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Dim g As Graphics = e.Graphics
' no difference when changing the SmoothingMode '
g.SmoothingMode = SmoothingMode.AntiAlias
Using pen As New Pen(Color.Blue, 3)
g.DrawLine(pen, X1, Y1, X2, Y2)
End Using
' MyBase.OnPaint(e) '
End Sub
I always have the same result, like this: alt text http://lh6.ggpht.com/_1TPOP7DzY1E/S3v1IbxlbCI/AAAAAAAADD4/q1Y9kP8wJ0g/s800/Capture2.png
=======
EDIT
updated the test:
Protected Overrides Sub OnPaint(ByVal e As System.Windows.Forms.PaintEventArgs)
Dim g As Graphics = e.Graphics
Dim oldmode As SmoothingMode = g.SmoothingMode
Using pen As New Pen(Color.Blue, 3)
g.SmoothingMode = SmoothingMode.AntiAlias
g.DrawLine(pen, X1, Y1, X2, Y2)
g.SmoothingMode = SmoothingMode.None
g.DrawLine(pen, X1 + 50, Y1, X2 + 50, Y2)
End Using
g.SmoothingMode = oldmode
g.Flush()
'MyBase.OnPaint(e)'
End Sub
Result (don't take in consideration labels and circles):
alt text http://lh3.ggpht.com/_1TPOP7DzY1E/S447qYvTqzI/AAAAAAAADE8/eP3kCLqQJbk/s800/Capture2.png
apparently smoothing mode is not taken inconsideration...
The SmoothingMode should definitely impact your output
Here's some settings I recently used for resizing an image with minimal quality loss:
graphics.SmoothingMode = SmoothingMode.HighQuality;
graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
graphics.PixelOffsetMode = PixelOffsetMode.HighQuality;
The InterpolationMode is probably not relevant for your example but the PixelOffsetMode might be. Let me spin up a quick test app.
Update: Here's the quick test app, SmoothingMode definitely impacts the lines I draw.
private void Form1_Load(object sender, EventArgs e)
{
foreach (var value in Enum.GetValues(typeof(SmoothingMode)))
{
_ComboBoxSmoothingMode.Items.Add(value);
}
foreach (var value in Enum.GetValues(typeof(PixelOffsetMode)))
{
_ComboBoxPixelOffsetMode.Items.Add(value);
}
_ComboBoxPixelOffsetMode.SelectedIndex = 0;
_ComboBoxSmoothingMode.SelectedIndex = 0;
}
private void _ButtonDraw_Click(object sender, EventArgs e)
{
using (Graphics g = _LabelDrawing.CreateGraphics())
{
g.Clear(Color.White);
if (_ComboBoxPixelOffsetMode.SelectedItem != null && (PixelOffsetMode)_ComboBoxPixelOffsetMode.SelectedItem != PixelOffsetMode.Invalid)
{
g.PixelOffsetMode = (PixelOffsetMode)_ComboBoxPixelOffsetMode.SelectedItem;
}
if (_ComboBoxSmoothingMode.SelectedItem != null && (SmoothingMode)_ComboBoxSmoothingMode.SelectedItem != SmoothingMode.Invalid)
{
g.SmoothingMode = (SmoothingMode)_ComboBoxSmoothingMode.SelectedItem;
}
using (Pen pen = new Pen(Color.Blue, 3))
{
g.DrawLines(pen, new[] { new Point(0, 0), new Point(25, 50), new Point(_LabelDrawing.Width - 25, _LabelDrawing.Height - 50), new Point(_LabelDrawing.Width, _LabelDrawing.Height), });
}
}
}
SmoothingMode: AntiAlias None
SmoothingMode.AntiAlias http://www.ccswe.com/temp/SmoothingMode_AntiAlias.png SmoothingMode.None http://www.ccswe.com/temp/SmoothingMode_None.png
Update: As Morbo pointed out if the Graphics
object presented to you in the PaintEventArgs
isn't the same Graphics
object that will ultimately be used for display then changing the smoothing might not have any effect. Although I would not expect such a drastic difference if that was a Graphics
object from a memory Image
or something.
Wish I could offer more. Maybe if I understood better what the LineShape
was giving you and your reasoning for using it over just using one of the Graphics.DrawLine() methods.
The reason I question your use of the LineShape
is that you are overriding it's OnPaint and drawing your own line. Seems like you could simplify your application and ditch the LineShape
but maybe I'm missing something.
Update: Ok that makes sense why you are using the LineShape
then. Only suggestion I can offer at this point is to override OnPaint in your panel or LineShape, try setting the smoothing mode there before calling the base event. Something like:
protected override void OnPaint(PaintEventArgs e)
{
e.Graphichs.SmoothingMode = SmoothingMode.AntiAlias;
base.OnPaint(e);
}
From what I can tell in Reflector, the PowerPack LineShape component paints using the Graphics object from the container's original Paint event. Changing properties on the Graphics object you're given could affect everything else in the container that paints after your shape.
What are your LineShape objects contained within in your sample? (If it's a custom-painted control, do you create a Bitmap at some point? How?) If they're inside of a custom control with a low color depth, that could be the source of the problem. LineShape draws antialiased by default on my machine.
What are your display settings set to? At least 24 bit color?
I can confirm that deriving a class from LineShape and overriding OnPaint like you showed does in fact affect the line rendering as expected. I also can confirm that both Power Pack 3.0 and the version in Visual Studio 2010 both specifically use AntiAlias in the LineShape.DrawInternal method.
I started with a blank .NET 2.0 Windows Forms app. I added the following class which is nearly identical to yours and a form which only contains the ShapeContainer and a diagonal MyLine shape.
Imports Microsoft.VisualBasic.PowerPacks
Public Class MyLine
Inherits LineShape
Protected Overrides Sub OnPaint(ByVal e As PaintEventArgs)
Dim g As Graphics = e.Graphics
'g.SmoothingMode = SmoothingMode.AntiAlias '
Using pen As New Pen(Color.Blue, 3)
g.DrawLine(pen, X1, Y1, X2, Y2)
End Using
'MyBase.OnPaint(e) '
End Sub
End Class
If I run the project with the above code as-is, the line is aliased (jagged). If I uncomment the SmoothingMode setting, the line becomes antialiased (smooth).
So it definitely should work. I know it seems like a dumb question but have you checked to make sure your code is getting hit in the debugger? Have you tried calling Graphics.Flush() immediately after your DrawLine?
Also, which version of the PowerPack are you using? Like I said I can see quite clearly in Reflector that LineShape.DrawInternal specifically sets the SmoothingMode to AntiAlias in a try/finally block. It restores the old smoothing mode before returning. But in your example you should never even hit this because you're not calling the base method.
If you love us? You can donate to us via Paypal or buy me a coffee so we can maintain and grow! Thank you!
Donate Us With