tags:

views:

148

answers:

1

Sorry if the title is a little cryptic. Basically I'm creating a zoom control in a c# forms app, the idea is that I can zoom an image by factors, ie. 1x, 2x, 4x, 8x. I need the image to remain pixelated, ie. nearest neighbors. The zooming works wonderfully except that when I select Interp mode to be nearest neighbors when working with the boundary pixels it defaults to the inner color. This is to say that the outer pixels appear to have half the width as the inner pixels, where the issue really comes in is when I add a tooltip to display the x,y co-ordinates of the current moused-over pixel it is thrown off. To be clear, the reason it is thrown off is because I calculate the current pixel as:

void m_pictureBox_MouseMove(object sender, MouseEventArgs e)
{
    int x = e.Location.X / m_zoomFactor;
    int y = e.Location.Y / m_zoomFactor;
}

and since the outer pixel are half the width... well you get the picture.

The drawing code is simply:

void m_pictureBox_Paint(object sender, PaintEventArgs e)
{
    if (m_pictureBox.Image!=null)
    {
        e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
        e.Graphics.ScaleTransform((float)m_zoomFactor, (float)m_zoomFactor);
        e.Graphics.DrawImage(m_pictureBox.Image, 0, 0);
    }            
}

The picture control is hosted within my custom 'ZoomControl' which is itself inherited from the 'Panel' control.

My question is basically, can any body help me resolve the boundary pixel issue and is there a better way to get zoom functionality?

+1  A: 

You also need to change Graphics.PixelOffsetMode. It defaults to None, which is okay for interpolation but not when you blow up the pixels to blocks. Change it to Half. For example:

  public partial class Form1 : Form {
    public Form1() {
      InitializeComponent();
    }

    private float mZoom = 10;

    protected override void OnPaint(PaintEventArgs e) {
      e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.Half;
      e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;
      Image img = Properties.Resources.SampleImage;
      RectangleF rc = new RectangleF(0, 0, mZoom * img.Width, mZoom * img.Height);
      e.Graphics.DrawImage(img, rc);
    }
  }
Hans Passant
Thank you it works perfectly
DeusAduro