【问题标题】:C# Application to Zoom in/out the image in a PictureBoxC#应用程序放大/缩小PictureBox中的图像
【发布时间】:2018-02-14 10:12:20
【问题描述】:

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

主要目标

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

参考

[ 这是我的表单,完全按照我的描述完成,在 PictureBox 中使用 SizeMode Zoom 制作了一个 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)
    {

    }
}

}

【问题讨论】:

  • 始终处理您制作的 Graphics 对象,将它们放在 using(...) { } 块中

标签: c# winforms image-processing


【解决方案1】:

Panel 内的图片框, 面板应将其 AutoSroll 设置为 True, 使用 SizeMode 缩放的图片框

trackbar的变化可以增加和减少内部picturebox的大小,以便外部面板自动滚动

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

【讨论】:

  • 于是熬夜研究了一下,想出了如下代码;反映在更新的主帖中
猜你喜欢
  • 1970-01-01
  • 2011-08-22
  • 1970-01-01
  • 1970-01-01
  • 2014-07-20
  • 1970-01-01
  • 2020-01-28
  • 1970-01-01
  • 2011-02-16
相关资源
最近更新 更多