【问题标题】:How do I make a PictureBox use Nearest Neighbor resampling?如何让 PictureBox 使用最近邻重采样?
【发布时间】:2010-09-06 22:45:09
【问题描述】:

我正在使用 StretchImage,因为该框可以通过拆分器调整大小。看起来默认是某种平滑的双线性过滤,导致我的图像模糊并有莫尔图案。

【问题讨论】:

  • 所以没有实际的方法可以做到这一点?以某种简单的方式?
  • @Luiscencio:看起来就是这样。您必须自己使用适当大小的新位图,然后使用 Graphics.DrawImage
  • 您应该标记 JYelton 答案。 :)

标签: c# .net winforms gdi+ picturebox


【解决方案1】:

我怀疑您将不得不通过 Image 类和 DrawImage 函数手动调整大小并响应 PictureBox 上的调整大小事件。

【讨论】:

    【解决方案2】:

    在 .net 中调整图像大小时,System.Drawing.Drawing2D.InterpolationMode 提供以下调整大小方法:

    • 双三次
    • 双线性
    • 高品质双三次
    • 高质量双线性
    • 最近邻
    • 默认

    【讨论】:

    • 我不明白这如何解决 OP 的问题。
    【解决方案3】:

    我做了一个 MSDN 搜索,结果发现有一篇关于此的文章,不是很详细,但概述了您应该使用绘制事件。

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

    我编辑了一个常用的图像缩放示例来使用此功能,见下文

    编辑自:http://www.dotnetcurry.com/ShowArticle.aspx?ID=196&AspxAutoDetectCookieSupport=1

    希望对你有帮助

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

    【讨论】:

    • 什么事件与您的 picBox_Paint_1 方法相关联?它会在你代码的其他部分。
    • 是的,它在表单设计器代码中:this.picBox.Paint += new System.Windows.Forms.PaintEventHandler(this.picBox_Paint_1);
    【解决方案4】:

    我也需要这个功能。我创建了一个继承 PictureBox 的类,覆盖 OnPaint 并添加了一个属性以允许设置插值模式:

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

    【讨论】:

    • 非常好。我认为 EmguCV 的 PanAndZoomPictureBox 也是如此。您是否知道这样做的任何性能问题?
    • 我没有任何可测量的性能差异以这种方式更改插值模式。
    • 可爱的答案。我建议海报的代码更完整一点,即添加 using System.Drawing.Drawing2D 或将完整的命名空间放在 InterpolationMode 声明的前面。
    • 请注意,通过清晰的缩放,您会看到图像在缩放时偏移了半个像素。要修复它,设置paintEventArgs.Graphics.PixelOffsetMode = PixelOffsetMode.Half;这个属性命名错误;将其设置为 Half 使其将整个事物向上和向左移动半个(缩放)像素。
    • @pelesl 为了清楚起见,我在 using 语句中添加了命名空间声明。
    猜你喜欢
    • 2012-10-23
    • 1970-01-01
    • 1970-01-01
    • 2016-10-08
    • 2021-12-02
    • 1970-01-01
    • 2011-12-06
    • 2016-10-20
    • 2023-03-24
    相关资源
    最近更新 更多