首页
学习
活动
专区
圈层
工具
发布
社区首页 >问答首页 >在PictureBox处于“缩放”模式时裁剪图像的正确部分

在PictureBox处于“缩放”模式时裁剪图像的正确部分
EN

Stack Overflow用户
提问于 2019-05-29 11:54:31
回答 1查看 1K关注 0票数 3

我有一个PictureBox1,它的sizemode设置为拉伸和PictureBox1。PictureBox1包含一个图像,让我选择其中的一部分,然后对其进行裁剪,并将裁剪后的部分存储在PictureBox2中。当sizemode被设置为拉伸,并且图片没有缩放时,它工作得很好,但是当我缩放它或将sizemode设置为缩放时,它就不能工作了。

工作示例-设置为“拉伸”的sizemode

用于裁剪图片部分的代码(原始源)

代码语言:javascript
复制
try
{
    float stretch1X = 1f * pictureBox1.Image.Width / pictureBox1.ClientSize.Width;
    float stretch1Y = 1f * pictureBox1.Image.Height / pictureBox1.ClientSize.Height;

    Point pt = new Point((int)(_mDown.X * stretch1X), (int)(_mDown.Y * stretch1Y));
    Size sz = new Size((int)((_mCurr.X - _mDown.X) * stretch1X),
                       (int)((_mCurr.Y - _mDown.Y) * stretch1Y));



    if (sz.Width > 0 && sz.Height > 0)
    {
        Rectangle rSrc = new Rectangle(pt, sz);
        Rectangle rDest = new Rectangle(Point.Empty, sz);

        Bitmap bmp = new Bitmap(sz.Width, sz.Height);
        using (Graphics G = Graphics.FromImage(bmp))
            G.DrawImage(pictureBox1.Image, rDest, rSrc, GraphicsUnit.Pixel);
        return bmp;
    }

    return null;
}
catch (Exception ex)
{
    throw ex;
}

我该如何正确计算?我如何使裁剪功能以某种方式工作,这样用户就可以放大/缩小图片的正确部分?

EN

回答 1

Stack Overflow用户

回答已采纳

发布于 2019-05-29 14:12:39

你需要用拉伸因子和偏移量来计算点。

对于Zoom,只有一个因子,因为ImagePictureBox的纵横比总是相同的,但是通常有一个偏移量;对于Stretch,您不需要偏移量,只需要2<>E29因子。

下面是一个使用2 PictureBoxes 2的例子,它显示了一个缩放的版本和剪裁的位图。它利用了一个通用函数ImageArea来确定大小和偏移量.

两个类级变量:

代码语言:javascript
复制
Point pDown = Point.Empty;
Rectangle rect = Rectangle.Empty;

三个鼠标事件:

代码语言:javascript
复制
private void PictureBox1_MouseDown(object sender, MouseEventArgs e)
{
    pDown = e.Location;
    pictureBox1.Refresh();
}

private void PictureBox1_MouseMove(object sender, MouseEventArgs e)
{
    if (!e.Button.HasFlag(MouseButtons.Left)) return;

    rect = new Rectangle(pDown, new Size(e.X - pDown.X, e.Y - pDown.Y));
    using (Graphics g = pictureBox1.CreateGraphics())
    {
        pictureBox1.Refresh();
        g.DrawRectangle(Pens.Orange, rect);
    }
}

private void PictureBox1_MouseUp(object sender, MouseEventArgs e)
{
    Rectangle iR = ImageArea(pictureBox2);
    rect = new Rectangle(pDown.X - iR.X, pDown.Y - iR.Y, 
                         e.X - pDown.X, e.Y - pDown.Y);
    Rectangle rectSrc = Scaled(rect, pictureBox2, true);
    Rectangle rectDest = new Rectangle(Point.Empty, rectSrc.Size);

    Bitmap bmp = new Bitmap(rectDest.Width, rectDest.Height);
    using (Graphics g = Graphics.FromImage(bmp))
    {
        g.DrawImage(pictureBox2.Image, rectDest, rectSrc, GraphicsUnit.Pixel);
    }
    pictureBox2.Image = bmp;
}

下面是一个有用的函数,它返回任何sizemode的picturebox中的实际图像区域。

代码语言:javascript
复制
Rectangle ImageArea(PictureBox pbox)
{
    Size si = pbox.Image.Size;
    Size sp = pbox.ClientSize;

    if (pbox.SizeMode == PictureBoxSizeMode.StretchImage) 
       return pbox.ClientRectangle;
    if (pbox.SizeMode == PictureBoxSizeMode.Normal ||
        pbox.SizeMode == PictureBoxSizeMode.AutoSize) 
       return new Rectangle(Point.Empty, si);
    if (pbox.SizeMode == PictureBoxSizeMode.CenterImage)
        return new Rectangle(new Point((sp.Width - si.Width) / 2,
                            (sp.Height - si.Height) / 2), si);

    //  PictureBoxSizeMode.Zoom
    float ri = 1f * si.Width / si.Height;
    float rp = 1f * sp.Width / sp.Height;
    if (rp > ri)
    {
        int width = si.Width * sp.Height / si.Height;
        int left = (sp.Width - width) / 2;
        return new Rectangle(left, 0, width, sp.Height);
    }
    else
    {
        int height = si.Height * sp.Width / si.Width;
        int top = (sp.Height - height) / 2;
        return new Rectangle(0, top, sp.Width, height);
    }
}

我们只需要偏移量来确定不缩放的矩形。我们还需要扩大规模:

代码语言:javascript
复制
Rectangle Scaled(Rectangle rect, PictureBox pbox, bool scale)
{
    float factor = GetFactor(pbox);
    if (!scale) factor = 1f / factor;
    return Rectangle.Round(new RectangleF(rect.X * factor, rect.Y * factor,  
                               rect.Width * factor, rect.Height * factor));
}

为此,需要知道比例因子,这取决于高宽比:

代码语言:javascript
复制
float GetFactor(PictureBox pBox)
{
    if (pBox.Image == null) return 0;
    Size si = pBox.Image.Size;
    Size sp = pBox.ClientSize;
    float ri = 1f * si.Width / si.Height;
    float rp = 1f * sp.Width / sp.Height;
    float factor = 1f * pBox.Image.Width / pBox.ClientSize.Width;
    if (rp > ri) factor = 1f * pBox.Image.Height / pBox.ClientSize.Height;
    return factor;
}

如果PictureBox放大或移出,将其放置在AutoScrolling Panel中并更改Pbox.Size,则此解决方案也能工作。

票数 4
EN
页面原文内容由Stack Overflow提供。腾讯云小微IT领域专用引擎提供翻译支持
原文链接:

https://stackoverflow.com/questions/56360036

复制
相关文章

相似问题

领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档