【问题标题】:C# Resize Image with No InterpolationC# 无插值调整图像大小
【发布时间】:2019-12-17 04:06:45
【问题描述】:

我知道这个问题经常被问到,但没有一个典型的答案能给出我需要的结果。我正在尝试像 Paint.exe 一样缩放灰度位图。我不希望插值,因此可以观察到原始的单个像素。我已经尝试过经常被推荐的 NearestNeighbor 方法,它很接近,但不是我想要的。

这就是我想要的:

这是我得到的:

这是我用来缩放和重绘图像的代码。

protected override void OnPaint(PaintEventArgs e)
{
    e.Graphics.PixelOffsetMode = PixelOffsetMode.Half;
    e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor;            
    e.Graphics.SmoothingMode = SmoothingMode.None;

    Matrix m = new Matrix();
    m.Scale(mScale, mScale, MatrixOrder.Append);
    e.Graphics.Transform = m;

    e.Graphics.TranslateTransform(this.AutoScrollPosition.X / mScale,this.AutoScrollPosition.Y / mScale);

    if (mImage != null) 
        e.Graphics.DrawImage(mImage, 0, 0);

    base.OnPaint(e);
}

当缩放起作用时,代码确实会对图像产生影响,并且更改 InterpolationMode 确实会改变图像。但是,没有任何设置组合得到我需要的结果。

有什么想法吗?

【问题讨论】:

  • 无法重现您的问题。原始图像是什么样的? mScale的值是多少?
  • mScale 是可变的,但在我发布的示例中,它设置为 5.0。图片如下:i.imgur.com/pwdcfH6.png?1
  • 仍然无法使用提供的代码重现您的问题。我得到的是第一张图片,而不是第二张。
  • 这可能根本无济于事——最近邻插值应该可以准确地为您提供您所追求的结果,但它可能有助于简化您正在做的事情并使用 DrawImage 的重载: msdn.microsoft.com/en-us/library/dbsak4dc%28v=vs.110%29.aspx。那个允许指定图像的目标宽度和高度,以便您可以按这种方式缩放它。这比通过矩阵变换更“直接”,并且可能减少可能导致插值错误的浮点数学运算量。也就是说,您发布的结果...
  • ... 看起来不像是一个简单的像素偏移/FP 问题,而是使用最近邻采样(双线性或双三次)以外的其他方法的结果。最近的邻居不应该给你源图像中不存在的像素值。就像健全性检查一样,但您可能想确保您实际上使用的是正确的输入图像,例如

标签: c# graphics paint interpolation antialiasing


【解决方案1】:

我正在尝试使用 C# 显示 16 位图像。我遇到了同样的问题,完全相同的像素中的颜色不一样。最后我用下面的示例代码解决了这个问题:

        protected override void OnPaint(PaintEventArgs e)
        {
            e.Graphics.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
            e.Graphics.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.NearestNeighbor; 
            e.Graphics.PixelOffsetMode = System.Drawing.Drawing2D.PixelOffsetMode.HighSpeed;
            e.Graphics.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.None;

            e.Graphics.Clear(Color.Black); //Clear the background with the black color

            if(m_bmp != null)  //if m_bmp == null, then do nothing.
            {
                //To calculate the proper display area's width and height that fit the window.
                if (this.Width / (double)this.Height > m_bmp.Width / (double)m_bmp.Height)
                {
                    m_draw_height = (int)(this.Height * m_roomRatio);
                    m_draw_width = (int)(m_bmp.Width / (double)m_bmp.Height * m_draw_height);
                }
                else
                {
                    m_draw_width = (int)(this.Width * m_roomRatio);
                    m_draw_height = (int)(m_bmp.Height / (double)m_bmp.Width * m_draw_width);
                }

                //To calculate the starting point.
                m_draw_x = (int)((this.Width - m_draw_width) / 2.0 + m_offsetX / 2.0);
                m_draw_y = (int)((this.Height - m_draw_height) / 2.0 + m_offsetY / 2.0);
                e.Graphics.DrawImage(m_bmp, m_draw_x, m_draw_y, m_draw_width, m_draw_height);

                //draw some useful information
                string window_info = "m_draw_x" + m_draw_x.ToString() + "m_draw_width" + m_draw_width.ToString();
                e.Graphics.DrawString(window_info, this.Font, new SolidBrush(Color.Yellow), 0, 20);
            }

顺便说一句,你为什么不尝试使用双缓冲来提高绘制图像的性能?

效果如下:

希望这会有所帮助。

【讨论】:

    猜你喜欢
    • 2017-01-24
    • 1970-01-01
    • 2018-05-18
    • 2012-06-23
    • 1970-01-01
    • 1970-01-01
    • 2023-03-17
    • 1970-01-01
    • 2018-06-07
    相关资源
    最近更新 更多