面板显示缩放图像

时间:2014-04-15 22:41:29

标签: c# .net winforms

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

imageBox1.Image = Properties.Resources.test;

不幸的是,由于某些原因,图像似乎已缩放 - 我无法滚动到它的边框。如果我使用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);
    }
}

2 个答案:

答案 0 :(得分:2)

DrawImage有很多变种,非常值得仔细检查它们。你为自己的目的选择了错误的一个。查看MSDN上的文档:

Graphics.DrawImage Method (Image, Int32, Int32) 
...
Draws the specified image, using its original physical size, 
at the location specified by a coordinate pair.
乍一看这听起来不错。 '物理尺寸' - 那不是像素吗?但请继续阅读MSDN:

Remarks

An Image stores a value for pixel width and a value for horizontal resolution 
(dots per inch). The physical width, measured in inches, of an image is 
the pixel width  divided by the horizontal resolution. For example, 
an image with a pixel width of 216 and a horizontal resolution of 72 dots 
per inch has a physical width of 3 inches. Similar remarks apply to pixel 
height and physical height.

The DrawImage method draws an image using its physical size, so the image will 
have its correct size in inches regardless of the resolution (dots per inch) 
of the display device. For example, suppose an image has a pixel width of 216 
and a horizontal resolution of 72 dots per inch. If you call DrawImage to
draw that image on a device that has a resolution of 96 dots per inch, 
the pixel width of the rendered image will be (216/72)*96 = 288.

哎呀,毕竟这不是关于像素的!这是关于显示器和图像嵌入其中的分辨率。如果你想获得图像,这是很好的。所有打印机上都打印

但您希望图像的像素与显示器的像素相匹配。您可以使图像的分辨率适应您的屏幕;但那不适用于不同的屏幕。所以这个DrawImage调用对你不起作用..

因此,您应该非常简单地使用图像所具有的像素数并将其提供给正确的DrawImage调用:

e.Graphics.DrawImage(mImage, 0, 0, mImage.Width, mImage.Height);

现在它不会扭曲图像,而是将一个图像像素放在一个屏幕像素上。

编辑:注意:我的OP中错误引用了MSDN;现在正确的(但你的目的是错误的)方法调用在第一部分引用..

答案 1 :(得分:2)

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

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

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

选择“正确”的方法并不是那么明显,你可能应该考虑添加另一个属性,以便你可以根据需要进行更改。