C# 面板显示缩放图像

C# 面板显示缩放图像,c#,.net,winforms,C#,.net,Winforms,我用这段代码在win窗体上绘制一个可滚动的面板。ImageBox是512x512,我使用的图像是1024x768(作为资源添加): 不幸的是,由于某些原因,图像似乎被缩放了——我无法滚动到它的边框。如果我使用512x512图像,它不适合ImageBox,它似乎被裁剪了。你知道这是怎么回事吗 using System; using System.Drawing; using System.Windows.Forms; class ImageBox : Panel { public Ima

我用这段代码在win窗体上绘制一个可滚动的面板。ImageBox是512x512,我使用的图像是1024x768(作为资源添加):

不幸的是,由于某些原因,图像似乎被缩放了——我无法滚动到它的边框。如果我使用512x512图像,它不适合ImageBox,它似乎被裁剪了。你知道这是怎么回事吗

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

class ImageBox : Panel {
    public ImageBox() {
        this.AutoScroll = true;
        this.DoubleBuffered = true;
    }
    private Image mImage;
    public Image Image {
        get { return mImage; }
        set {
            mImage = value;
            if (mImage != null) this.AutoScrollMinSize = mImage.Size;
            else this.AutoScrollMinSize = new Size(0, 0);
            this.Invalidate();
        }
    }
    protected override void OnPaint(PaintEventArgs e) {
        e.Graphics.TranslateTransform(this.AutoScrollPosition.X, this.AutoScrollPosition.Y);
        if (mImage != null) e.Graphics.DrawImage(mImage, 0, 0);
        base.OnPaint(e);
    }
}

DrawImage有许多变体,值得仔细检查。你为你的目的选错了一个。查看MSDN上的文档:

乍一看,这听起来不错物理尺寸——这不是像素吗?但请继续阅读MSDN:

哎哟,这毕竟不是像素的问题!这是关于显示器和图像嵌入其中的分辨率。如果您希望在所有打印机上正确打印图像,例如,这是很好的

但是您希望图像的像素与显示器的像素匹配。可以根据屏幕调整图像的分辨率;但这在不同的屏幕上是行不通的。所以这个DrawImage呼叫对你不起作用

因此,您应该非常简单地使用图像的像素数,并将它们输入到右DrawImage调用中:

e.Graphics.DrawImage(mImage, 0, 0, mImage.Width, mImage.Height);
现在它不会扭曲图像,而是将一个图像像素放到一个屏幕像素上


编辑:注意:我在OP中错误引用了MSDN;现在,在第一部分中引用了正确的(但对于您来说是错误的)方法调用。

DrawImage有许多变体,值得仔细检查它们。你为你的目的选错了一个。查看MSDN上的文档:

乍一看,这听起来不错物理尺寸——这不是像素吗?但请继续阅读MSDN:

哎哟,这毕竟不是像素的问题!这是关于显示器和图像嵌入其中的分辨率。如果您希望在所有打印机上正确打印图像,例如,这是很好的

但是您希望图像的像素与显示器的像素匹配。可以根据屏幕调整图像的分辨率;但这在不同的屏幕上是行不通的。所以这个DrawImage呼叫对你不起作用

因此,您应该非常简单地使用图像的像素数,并将它们输入到右DrawImage调用中:

e.Graphics.DrawImage(mImage, 0, 0, mImage.Width, mImage.Height);
现在它不会扭曲图像,而是将一个图像像素放到一个屏幕像素上


编辑:注意:我在OP中错误引用了MSDN;现在,在第一部分中引用了正确的(但对您来说是错误的)方法调用。

这是图像分辨率的问题,它小于您的显示器分辨率。很不寻常

对此,有不止一种解决方法@TaW的方法可行,但有利于监视器分辨率。您将获得更清晰的图像,但它不会接近最初记录的图像大小。另一种方法是像DrawImage()一样保持物理大小,并相应地调整滚动条。将图像属性设置器更改为:

    set {
        mImage = value;
        if (value == null) this.AutoScrollMinSize = new Size(0, 0);
        else {
            var size = value.Size;
            using (var gr = this.CreateGraphics()) {
                size.Width = (int)(size.Width * gr.DpiX / value.HorizontalResolution);
                size.Height = (int)(size.Height * gr.DpiY / value.VerticalResolution);
            }
            this.AutoScrollMinSize = size;
        }
        this.Invalidate();
    }

挑选“正确”的方法不是很明显,你可能应该考虑添加另一个属性,这样你可以根据需要改变它。

< P>这是一个问题,图像的分辨率,它小于你的显示分辨率。很不寻常

对此,有不止一种解决方法@TaW的方法可行,但有利于监视器分辨率。您将获得更清晰的图像,但它不会接近最初记录的图像大小。另一种方法是像DrawImage()一样保持物理大小,并相应地调整滚动条。将图像属性设置器更改为:

    set {
        mImage = value;
        if (value == null) this.AutoScrollMinSize = new Size(0, 0);
        else {
            var size = value.Size;
            using (var gr = this.CreateGraphics()) {
                size.Width = (int)(size.Width * gr.DpiX / value.HorizontalResolution);
                size.Height = (int)(size.Height * gr.DpiY / value.VerticalResolution);
            }
            this.AutoScrollMinSize = size;
        }
        this.Invalidate();
    }

选择“正确”的方法并不那么明显,你可能应该考虑增加另一个属性,这样你就可以根据需要修改它。请参阅“”,其中的共识是“不,他们不应该”。winform中面板的大小是多少?是设置为停靠满还是什么?我已经编辑了你的标题。请参阅“”,其中的共识是“不,他们不应该”。winform中面板的大小是多少?你是专家,但我想知道:当它以自己的尺寸绘制时,为什么图像会失真?(假设是二次像素)你是专家,但我想知道:当图像以自己的尺寸绘制时,为什么会失真?(假设为二次像素。)
    set {
        mImage = value;
        if (value == null) this.AutoScrollMinSize = new Size(0, 0);
        else {
            var size = value.Size;
            using (var gr = this.CreateGraphics()) {
                size.Width = (int)(size.Width * gr.DpiX / value.HorizontalResolution);
                size.Height = (int)(size.Height * gr.DpiY / value.VerticalResolution);
            }
            this.AutoScrollMinSize = size;
        }
        this.Invalidate();
    }