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

问题描述 投票:0回答:1

总的来说,我对编程有点陌生,但我渴望了解更多,我想知道是否有人可以帮助我提出一个想法。

(主要目标)

我想制作一个由 C# Windows 窗体应用程序组成的简单程序,该程序在 PictureBox 中显示预设图像(尺寸为 6000x6000 像素,SizeMode 设置为 Zoom,以便整个图像立即在窗体上可见)。实际上整个表单,在表单底部保留一个空间,我想在其中显示一个允许您放大和缩小图像的轨迹栏;以及 PictureBox 底部的水平滚动条和 PictureBox 右侧的垂直滚动条,用于在缩放地图时滚动地图,我希望能够通过单击来控制这些滚动条并在 PictureBox 上沿相应方向拖动(首选,但不确定是否可能)或使用鼠标上的滚轮(可能更容易,但再次不确定)。

(参考)

[ 这里是我完全按照我的描述完成的表单,使用 SizeMode Zoom 在 PictureBox 中使用 6000x6000 放置支架演示纹理作为示例 - 这已得到处理,问题的下一部分更新如下:]

附录

我遇到的唯一问题是代码,因为我在该部门几乎是新手。我一直在努力学习 Visual Studio 的工作流程,但我确实需要一些帮助。

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

更新:

在对这个主题进行研究并花时间进行一些思考之后,我想出了下面列出的代码;但我的问题是,当我将图像平移太远时,图像会被拉得太远,从而当图像被平移/拉太远到一个角落时会暴露其后面的面板。另外,当我缩小得太远时,图像会变得比图片框小得多。

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)
    {

    }
}

}

c# winforms image-processing
1个回答
0
投票

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

改变轨迹栏可以增大或减小内部图片框的大小,使外部面板自动滚动

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

© www.soinside.com 2019 - 2024. All rights reserved.