GDI+ How to change Line SmoothingMode?
Asked Answered
A

4

7

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...

Ative answered 17/2, 2010 at 12:36 Comment(1)
Are you saying the line does not get anti-aliased? Regardless of the setting?Treasonous
A
0

The question was in my development mode: via Remote Desktop Connection on a virtual PC.

The RDC does not take in consideration in my case the AntiAlias graphics property.

more details: Have you had problems developing on a Virtual PC?

Thanks everybody for participating, sorry that is wasn't a really .NET problem.

Ative answered 3/3, 2010 at 16:47 Comment(1)
It's most likely color depth as RDP on Vista and up will definitely antialias. The difference being Vista supports high color depth.Stillhunt
F
4

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);
}
Forestforestage answered 26/2, 2010 at 17:22 Comment(9)
thank you, Cory. However I draw not simple lines, but a overrides PowerPacks.LineShape OnPaint, maybe this impacts. Edit. Read Morbo's comment. Will try to change the parent.Ative
Finally, what I don't understand that what smoothing mode changing have any effect on the line drawing, when I override the OnPaint and don't use the base.OnPaint logic at all for my custom line.Ative
@serhio: Not sure I understand. Are you saying that if you uncomment MyBase.OnPaint(e) the SmoothingMode works?Forestforestage
the SmoothingMode does not work ever. I can't ditch LineShape. It does HitTest(Clicks), MouseOver and repainting logic.Ative
Thanks, Cory. Your code in the second update is almost the same I have in my example. I uncommitted MyBase.OnPaint(e), but don't see a difference between lines representation with or without AntiAlias for that LineShapes.Ative
@serhio: In your example who's OnPaint are you overriding? The LineShape or the Panel? (I don't even know that LineShape has an OnPaint) Maybe if you tried switching that? Grapsing at straws here since I don't have a good answer :-)Forestforestage
LineShape is a GUI component, so it have OnPaint. in my code I inherit the LineShape, so I override the LineShape's OnPaint.Ative
@serhio: Have you tried inheriting ShapeContainer and overriding it's OnPaint instead of the individual LineShape s? It's another shot in the dark...Forestforestage
OK so I am commenting 13 years later, but I had the same issue. It turns out that some of my graphics were honouring the SmoothingMode and others weren't, and it was driving me nutty. It turns out that I was putting some of my graphics in a new GraphicsContainer. Despite the documentation stating that all rendering quality state is maintained, it seems that this was not the case. I had to call BeginContainer, then update my quality properties again, and then I had consistent smoothing.Spectrohelioscope
M
2

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.

Metaphysics answered 26/2, 2010 at 17:47 Comment(3)
+1: For digging under the hood to find out what the PowerPack LineShape is actually doing.Forestforestage
I draw lineShapes on a custom panel. How do I change this panel drawing properties? As you can see, I override OnPaint, so e.Graphics isn't the parent graphics that are passed to? Also as You can see from my code, I don't use base.OnPaintAtive
I seem to found the problem see here: #2371238Ative
S
2

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.

Stillhunt answered 3/3, 2010 at 5:59 Comment(3)
I use the latest version of PowerPack - 3.0. I made a test also on a other specially created new project... AntiAlias is working work there... something strange.Ative
I seem to found the problem see here: #2371238Ative
Ahh yes Remote Desktop is limited to 16 bit color before Vista. That would do it.Stillhunt
A
0

The question was in my development mode: via Remote Desktop Connection on a virtual PC.

The RDC does not take in consideration in my case the AntiAlias graphics property.

more details: Have you had problems developing on a Virtual PC?

Thanks everybody for participating, sorry that is wasn't a really .NET problem.

Ative answered 3/3, 2010 at 16:47 Comment(1)
It's most likely color depth as RDP on Vista and up will definitely antialias. The difference being Vista supports high color depth.Stillhunt

© 2022 - 2024 — McMap. All rights reserved.