Logo Questions Linux Laravel Mysql Ubuntu Git Menu
 

How do I make a PictureBox use Nearest Neighbor resampling?

I am using StretchImage because the box is resizable with splitters. It looks like the default is some kind of smooth bilinear filtering, causing my image to be blurry and have moire patterns.

like image 756
Jared Updike Avatar asked Aug 26 '08 23:08

Jared Updike


3 Answers

I needed this functionality also. I made a class that inherits PictureBox, overrides OnPaint and adds a property to allow the interpolation mode to be set:

using System.Drawing.Drawing2D;
using System.Windows.Forms;

/// <summary>
/// Inherits from PictureBox; adds Interpolation Mode Setting
/// </summary>
public class PictureBoxWithInterpolationMode : PictureBox
{
    public InterpolationMode InterpolationMode { get; set; }

    protected override void OnPaint(PaintEventArgs paintEventArgs)
    {
        paintEventArgs.Graphics.InterpolationMode = InterpolationMode;
        base.OnPaint(paintEventArgs);
    }
}
like image 136
JYelton Avatar answered Nov 16 '22 09:11

JYelton


I suspect you're going to have to do the resizing manually thru the Image class and DrawImage function and respond to the resize events on the PictureBox.

like image 23
Joel Lucsy Avatar answered Nov 16 '22 09:11

Joel Lucsy


I did a MSDN search and turns out there's an article on this, which is not very detailed but outlines that you should use the paint event.

http://msdn.microsoft.com/en-us/library/k0fsyd4e.aspx

I edited a commonly available image zooming example to use this feature, see below

Edited from: http://www.dotnetcurry.com/ShowArticle.aspx?ID=196&AspxAutoDetectCookieSupport=1

Hope this helps

    private void Form1_Load(object sender, EventArgs e)
    {
        // set image location
        imgOriginal = new Bitmap(Image.FromFile(@"C:\images\TestImage.bmp"));
        picBox.Image = imgOriginal;

        // set Picture Box Attributes
        picBox.SizeMode = PictureBoxSizeMode.StretchImage;

        // set Slider Attributes
        zoomSlider.Minimum = 1;
        zoomSlider.Maximum = 5;
        zoomSlider.SmallChange = 1;
        zoomSlider.LargeChange = 1;
        zoomSlider.UseWaitCursor = false;

        SetPictureBoxSize();

        // reduce flickering
        this.DoubleBuffered = true;
    }

    // picturebox size changed triggers paint event
    private void SetPictureBoxSize()
    {
        Size s = new Size(Convert.ToInt32(imgOriginal.Width * zoomSlider.Value), Convert.ToInt32(imgOriginal.Height * zoomSlider.Value));
        picBox.Size = s;
    }


    // looks for user trackbar changes
    private void trackBar1_Scroll(object sender, EventArgs e)
    {
        if (zoomSlider.Value > 0)
        {
            SetPictureBoxSize();
        }
    }

    // redraws image using nearest neighbour resampling
    private void picBox_Paint_1(object sender, PaintEventArgs e)
    {
        e.Graphics.InterpolationMode = InterpolationMode.NearestNeighbor;
        e.Graphics.DrawImage(
           imgOriginal,
            new Rectangle(0, 0, picBox.Width, picBox.Height),
            // destination rectangle 
            0,
            0,           // upper-left corner of source rectangle
            imgOriginal.Width,       // width of source rectangle
            imgOriginal.Height,      // height of source rectangle
            GraphicsUnit.Pixel);
    }
like image 3
Alex D Avatar answered Nov 16 '22 09:11

Alex D