C#应用程序放大/缩小PictureBox中的图像

时间:2017-09-06 03:40:36

标签: c# winforms image-processing

我对编程总体上有些新意,但我渴望了解更多内容,我想知道是否有人可以帮我解决问题。

主要目标

我想制作一个简单的程序,它包含一个C#Windows窗体应用程序,它将在PictureBox中显示预设图像(尺寸为6000x6000像素,SizeMode设置为Zoom,以便整个图像在窗体上可见)实际上占用整个表格,除了表格底部的空间,我想要显示一个TrackBar,可以让你放大和缩小图像;以及PictureBox底部的水平滚动条,以及PictureBox右侧的垂直滚动条,可以在缩放时滚动地图,我希望能够通过单击来控制这些滚动条并在PictureBox上以相应的方向拖动(首选但不确定是否可行)或使用鼠标上的滚轮(可能更容易但又不确定)。

(的 参考

[ 这是我完全按照我的描述完成的表单,使用SizeMode Zoom在PictureBox中使用6000x6000展示位置持有者演示纹理,作为示例 - 这已被处理,问题的下一部分在下面更新:]

(的 附录

我遇到的唯一问题是代码,因为我在那个部门里几乎是新手。我一直在努力学习Visual Studio的工作流程,但我真的可以使用一些帮助。

非常感谢你提供任何可以帮助我的事情。

更新:

在对这个主题进行研究并花时间思考之后,我想出了下面列出的代码;但我的问题是,当我将图像平移太远时,图像被允许被拉得太远,因此当图像被平移/拉到一个角落时,将图像暴露在它后面。此外,当我放大太远时,图像可以变得比Picturebox小。

Panning issue, the grey parts of the panel are the problem

Zoom issue, the grey parts of the panel are the problem

所以,我的最后一个问题:我将如何修改下面的代码以“锁定”我正在平移的图像并从允许平移或缩放到其框架之外进行缩放并将面板暴露在它背后?

public partial class ImageZoomMainForm : Form
{
    Image img;
    Point mouseDown;
    int startx = 0;
    int starty = 0;
    int imgx = 0; 
    int imgy = 0;

    bool mousepressed = false;  
    float zoom = 1;

    public ImageZoomMainForm()
    {

        InitializeComponent();
        string imagefilename = @"..\..\ViewPort_MAIN.tif";
        img = Image.FromFile(imagefilename);

        Graphics g = this.CreateGraphics();








        zoom = ((float)pictureBox.Width / (float)img.Width) * (img.HorizontalResolution / g.DpiX);

        pictureBox.Paint += new PaintEventHandler(imageBox_Paint);
    }

    private void pictureBox_MouseMove(object sender, EventArgs e)
    {
        MouseEventArgs mouse = e as MouseEventArgs;

        if (mouse.Button == MouseButtons.Left)
        {
            Point mousePosNow = mouse.Location;

            int deltaX = mousePosNow.X - mouseDown.X; 
            int deltaY = mousePosNow.Y - mouseDown.Y;

            imgx = (int)(startx + (deltaX / zoom));  
            imgy = (int)(starty + (deltaY / zoom));

            pictureBox.Refresh();
        }
    }

    private void imageBox_MouseDown(object sender, EventArgs e)
    {
        MouseEventArgs mouse = e as MouseEventArgs;

        if (mouse.Button == MouseButtons.Left)
        {
            if (!mousepressed)
            {
                mousepressed = true;
                mouseDown = mouse.Location;
                startx = imgx;
                starty = imgy;
            }
        }
    }

    private void imageBox_MouseUp(object sender, EventArgs e)
    {
        mousepressed = false;
    }

    protected override void OnMouseWheel(MouseEventArgs e)
    {
        float oldzoom = zoom;

        if (e.Delta > 0)
        {
            zoom += 0.1F;
        }

        else if (e.Delta < 0)
        {
            zoom = Math.Max(zoom - 0.1F, 0.01F);
        }

        MouseEventArgs mouse = e as MouseEventArgs;
        Point mousePosNow = mouse.Location;

        int x = mousePosNow.X - pictureBox.Location.X;    
        int y = mousePosNow.Y - pictureBox.Location.Y;

        int oldimagex = (int)(x / oldzoom);  
        int oldimagey = (int)(y / oldzoom);

        int newimagex = (int)(x / zoom);     
        int newimagey = (int)(y / zoom);

        imgx = newimagex - oldimagex + imgx;  
        imgy = newimagey - oldimagey + imgy;

        pictureBox.Refresh();  


    }

    private void imageBox_Paint(object sender, PaintEventArgs e)
    {
        e.Graphics.InterpolationMode = InterpolationMode.HighQualityBicubic;
        e.Graphics.ScaleTransform(zoom, zoom);
        e.Graphics.DrawImage(img, imgx, imgy);
    }



    protected override bool ProcessCmdKey(ref Message msg, Keys keyData)
    {
        const int WM_KEYDOWN = 0x100;
        const int WM_SYSKEYDOWN = 0x104;

        if ((msg.Msg == WM_KEYDOWN) || (msg.Msg == WM_SYSKEYDOWN))
        {
            switch (keyData)
            {
                case Keys.Right:
                    imgx -= (int)(pictureBox.Width * 0.1F / zoom);
                    pictureBox.Refresh();
                    break;

                case Keys.Left:
                    imgx += (int)(pictureBox.Width * 0.1F / zoom);
                    pictureBox.Refresh();
                    break;

                case Keys.Down:
                    imgy -= (int)(pictureBox.Height * 0.1F / zoom);
                    pictureBox.Refresh();
                    break;

                case Keys.Up:
                    imgy += (int)(pictureBox.Height * 0.1F / zoom);
                    pictureBox.Refresh();
                    break;

                case Keys.PageDown:
                    imgy -= (int)(pictureBox.Height * 0.90F / zoom);
                    pictureBox.Refresh();
                    break;

                case Keys.PageUp:
                    imgy += (int)(pictureBox.Height * 0.90F / zoom);
                    pictureBox.Refresh();
                    break;
            }
        }

        return base.ProcessCmdKey(ref msg, keyData);
    }

    private void ImageZoomMainForm_Load(object sender, EventArgs e)
    {

    }
}

}

1 个答案:

答案 0 :(得分:0)

面板内的图片框, 面板应设置为AutoSroll为True, SizeMode to Zoom

的图片框

轨迹栏更改可以增加和减少内部图片框的大小,以便外部面板将自动滚动

使用图片框的几个鼠标事件也可以拖动。