简体   繁体   English

面板显示缩放的图像

[英]Panel displays scaled images

I am using this code to draw a scrollable panel on win form. 我正在使用此代码在获胜表格上绘制可滚动面板。 The ImageBox is 512x512 and image I am using is 1024x768 (added as resource): ImageBox是512x512,我正在使用的图像是1024x768(作为资源添加):

imageBox1.Image = Properties.Resources.test;

Unfortunately, it seems like image is scaled for some reasons - I cannot scroll to it's border. 不幸的是,由于某些原因,图像似乎已缩放-我无法滚动到其边框。 If I use 512x512 image, it doesn't fit the ImageBox, it seems cropped. 如果我使用512x512的图片,则它不适合ImageBox,似乎已被裁剪。 Any ideas what is going on here? 有什么想法吗?

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 has many variants and it is well worth checking them all out carefully. DrawImage有许多变体,非常值得仔细检查一下。 You have chosen the wrong one for your purpose. 您选择了错误的目的。 Look at the doc at MSDN: 查看MSDN上的文档:

 Graphics.DrawImage Method (Image, Int32, Int32) ... Draws the specified image, using its original physical size, at the location specified by a coordinate pair. 

At first glance this sounds good. 乍一看,这听起来不错。 'Physical size' - isn't that pixels? “物理尺寸”-不是像素吗? But read on at MSDN: 但是请继续阅读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. 

Ouch, that's not about pixels after all! 哎呀,那根本不是关于像素! It is about displays and the resolution the image has embedded in it..This is good if you want to get the image eg printed right on all printers. 它与显示器和图像所嵌入的分辨率有关。如果要获取图像(例如,在所有打印机上正确打印) ,这很好。

But you want the pixels of the image to match the pixels of the display. 但是您希望图像的像素与显示器的像素匹配。 You could adapt the resolution of the image to your screen; 可以根据屏幕调整图像的分辨率; but that wouldn't work for a different screen. 但这不适用于其他屏幕。 So this DrawImage call will not work for you.. 因此,此DrawImage调用对您不起作用。

So you should, quite simply, use the number of pixels your image has and feed them into the right DrawImage call: 因此,您应该非常简单地使用图像的像素数,并将其输入到正确的DrawImage调用中:

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

Now it will not distort the image but put one image pixel onto one screen pixel.. 现在它不会扭曲图像,而是将一个图像像素放到一个屏幕像素上。

Edit: Note: I had misquoted MSDN in my OP; 编辑:注意:我在OP中错误地引用了MSDN; now the right (but wrong for your purpose) method call is quoted in the first part.. 现在,在第一部分中引用了正确的(但出于您的目的错误)方法调用。

It is an issue with the resolution of the image, it is less than the resolution of your display. 这是图像分辨率的问题,它小于显示器的分辨率。 Pretty unusual. 很不寻常。

There is more than one workaround for this. 有多种解决方法。 @TaW's approach works but favors the monitor resolution. @TaW的方法有效,但有利于监视器分辨率。 You'll get a sharper image but it will not be close to the image size as originally recorded. 您将获得更清晰的图像,但它不会接近原始记录的图像尺寸。 The other approach is to keep the physical size, like DrawImage() does, and adjust the scrollbars accordingly. 另一种方法是保持物理大小,就像DrawImage()一样,并相应地调整滚动条。 Change the Image property setter to: 将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();
    }

Picking the "right" approach is not so obvious, you probably ought to consider adding another property so you can change it as needed. 选择“正确”的方法并不是很明显,您可能应该考虑添加另一个属性,以便可以根据需要进行更改。

声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.

 
粤ICP备18138465号  © 2020-2024 STACKOOM.COM