locked
Drawing without AntiAliasing? RRS feed

  • Question

  • User-1219866711 posted

    Hello,

    I'm new to .NET and I wanted to draw a simple, vertical, 1px line on an image. However, the line always gets "smoothed" even though I tried everything in System.Drawing.Graphics to make it stop.

    Here's an image (zoomed in) of what I mean:


    Here's my code:

    Bitmap map = new Bitmap("world.png");

    Graphics g = Graphics.FromImage(map);
    g.SmoothingMode = SmoothingMode.None;
    g.InterpolationMode = InterpolationMode.NearestNeighbor;

    g.DrawLine(new Pen(Color.FromArgb(255, 0, 0)), 10, 10, 10, 100);
    g.Dispose();

    //...save image...



    Any help would be appreciated!

    Sunday, March 21, 2010 11:50 AM

Answers

  • User1439985827 posted

    As far as I can tell, that is the way to produce the best quality images in JPEG using .NET. If this isn't suitable, I'd recommend another image format, or saving them as PNG/BMP and using a 3rd party tool to process them into JPEGs. 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, March 22, 2010 10:55 PM

All replies

  • User1439985827 posted

    I don't think the issue is that it is aliasing. Infact the default behavior is it won't alias. This code does what you want it to do:

    Bitmap bmp = new Bitmap(500,500);
    Graphics g = Graphics.FromImage(bmp);
    g.DrawLine(new Pen(Color.Red, 5f), 10, 10, 10, 480);
    g.Save();
    bmp.Save(".\\out.bmp", ImageFormat.Bmp);


    What I think you are seeing is possibly because you are saving it in a lossy compression like JPEG which causes it to appear to be aliased. Were you saving your image as a JPEG?

    Sunday, March 21, 2010 6:18 PM
  • User-1219866711 posted

    Wow, you're right. I can't believe I didn't think of that. I've been using the usual JPEG-lib before and also Photoshop's "Save as JPEG" but I have never ever seen a JPEG compression this bad. It works fine as BMP and PNG but even when setting the quality to "100" the .NET-implementation is really really bad. Is there any way to improve this or am I doing something wrong?

    uint compression = 100;
    ImageCodecInfo imageEncoderJpeg = null;
    
    ImageCodecInfo[] encoders = ImageCodecInfo.GetImageEncoders();
    foreach(ImageCodecInfo info in encoders)
    {
    	if(info.FormatID == ImageFormat.Jpeg.Guid)
    	{
    		imageEncoderJpeg = info;
    		break;
    	}
    }
    
    if(imageEncoderJpeg == null)
    	return;
    
    EncoderParameters parameters = new EncoderParameters(2);
    parameters.Param[0] = new EncoderParameter(System.Drawing.Imaging.Encoder.Quality, (long)compression);
    parameters.Param[1] = new EncoderParameter(System.Drawing.Imaging.Encoder.Compression, (long)compression);
    
    image.Save(path, imageEncoderJpeg, parameters);



    Monday, March 22, 2010 11:18 AM
  • User1439985827 posted

    As far as I can tell, that is the way to produce the best quality images in JPEG using .NET. If this isn't suitable, I'd recommend another image format, or saving them as PNG/BMP and using a 3rd party tool to process them into JPEGs. 

    • Marked as answer by Anonymous Thursday, October 7, 2021 12:00 AM
    Monday, March 22, 2010 10:55 PM
  • User-1219866711 posted

    I found out what the problem is. NET uses standard subsampling (4:2:2) when saving JPEGs, while every one else (e.g. Photoshop) uses no subsampling (4:4:4) when saving JPEG with a quality over 50%.

    So, all I'd need to do is disable subsampling in NET - but that doesn't seem to be possible (maybe it's possible with Encoder.ChrominanceTable or Encoder.LuminanceTable but I have no idea how to do that and the documentation isn't helpful). I just spend searching the Internet with all possible keywords but it seems like only a handful of people wanted to do that and no one really succeeded (except one guy, but he didn't post an answer).

    I'm hoping someone here might have a clue...

    Monday, March 29, 2010 4:24 PM
  • User1439985827 posted

    Interesting discovery... I'll play around with it and see if I can find out. Thanks for the tip! 

    Tuesday, March 30, 2010 8:53 AM
  • User-1219866711 posted

    Wow, thank you for your effort trying to solve this! It'd be pretty cool if you happen to find a solution :)

    Tuesday, March 30, 2010 1:09 PM
  • User1439985827 posted

    Most solutions I was able to find were wrapping 3rd party libraries. There doesn't appear to be any known way, that I could find, to get the .NET Framework to do this itself. 

    Thursday, April 1, 2010 11:24 PM