代码之家  ›  专栏  ›  技术社区  ›  DeusAduro

paint.exe样式缩放,近邻插值半边界像素

  •  4
  • DeusAduro  · 技术社区  · 15 年前

    对不起,如果标题有点晦涩。基本上,我是在一个C窗体应用程序中创建一个缩放控件,其思想是我可以按因子缩放图像,即1X、2X、4X、8X。我需要图像保持像素化,即最近的邻居。缩放效果非常好,除了当我选择interp模式作为最近的邻居使用边界像素时,它默认为内部颜色。这就是说,外部像素的宽度似乎是内部像素的一半,真正的问题是,当我添加一个工具提示来显示当前鼠标悬停在像素上的x,y坐标时,它被抛出。很明显,它被丢弃的原因是我将当前像素计算为:

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

    因为外像素是宽度的一半…好吧,你明白了。

    绘图代码很简单:

    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);
        }            
    }
    

    图片控件宿主在我的自定义“ZoomControl”中,该自定义“ZoomControl”本身继承自“Panel”控件。

    我的问题是,任何物体都能帮助我解决边界像素问题吗?有没有更好的方法来获得缩放功能?

    1 回复  |  直到 15 年前
        1
  •  5
  •   Hans Passant    15 年前

    您还需要更改graphics.pixeloffsetmode。它默认为“无”,这对于插值是可以的,但当您将像素放大为块时则不行。把它改成一半。例如:

      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);
        }
      }