使用固定大小的可拖动图片框裁剪图像拖动、图像、大小、图片

2023-09-07 08:52:14 作者:清水入喉

我工作的一个WinForms项目,涉及种植的图像。我的目标是通过使用一个固定大小的可拖动PictureBox控件,允许用户选择他们想要的区域,以preserve做到这一点。

I'm working on a winforms project that involves cropping an image. My goal is to do this by using a fixed-size draggable picturebox control, allowing the user to select the area they want to preserve.

我的问题是,当我裁剪图像;它的作品的,但作物面积抵消了一点。下面是结果我得到:

My problem is when I crop the image; it "works", but the crop area offsets a little. Here's the result I get:

要澄清一下,我不是在谈论变焦,这是每个设计。请注意,橙色框大多集中在风暴之眼,但裁剪后的图像是没有的。

To clarify, I'm not talking about the zooming, that's per design. Notice the orange box is mostly focusing on the eye of the storm, but the cropped image is not.

这是我的code为作物操作:

This is my code for the crop operation:

private void tsbRecortar_Click(object sender, EventArgs e)
{
    Rectangle recorte = new Rectangle(pbxSeleccion.Location.X, pbxSeleccion.Location.Y, pbxSeleccion.Width, pbxSeleccion.Height);

    foto = recortarImagen(foto, recorte);
    pbxImagen.Image = foto;
}

private Image recortarImagen(Image imagen, Rectangle recuadro)
{
    try
    {
        Bitmap bitmap = new Bitmap(imagen);
        Bitmap cropedBitmap = bitmap.Clone(recuadro, bitmap.PixelFormat);

        return (Image)(cropedBitmap);
    }
    catch (Exception ex)
    {
        MessageBox.Show(ex.Message, "Error");

        return null;
    }
}

pbxSeleccion 的是可拖动的橙色矩形;其父是 pbxImage 的(我重新家长它形式的负载)。

pbxSeleccion is the draggable orange rectangle; its parent is pbxImage (I re-parent it on form's load).

正如你所看到的,我使用的坐标的 pbxSeleccion 的定义裁剪区域的起点,但并不如预期工作......有时候,我甚至得到一个出记忆的异常。

As you can see, I'm using the coordinates of pbxSeleccion to define the starting point of the crop area, but is not working as expected... sometimes, I even get an "Out of Memory" exception.

我觉得这是与如何父图片框的图像加载,一些关于如何保证金的处理引擎盖下,但没有我试图修复它...只是改变的偏移幅度。

I think this has to do with how the image loads in the parent picturebox, something about how the margin is handled "under the hood", but nothing I tried fixes it... just changes the magnitude of the offset.

在搜索网页和SO帮助了我很多,但对于这个具体问题,我似乎无法找到答案......请随时指出改进我的code,我的天堂重新编码为长,我是新的C#和.NET

Searching the web and SO has helped me a lot, but for this particular issue, I can't seem to find an answer... please, feel free to point out improvements to my code, I haven't been coding for long and I'm new to C# and .NET

任何帮助是非常AP preciated。干杯!

Any help is highly appreciated. Cheers!

推荐答案

假设你的原始图像显示在图片框。您橙色裁剪窗口的错误的位置通过。下面是更正后的$ C $下您:

Suppose your original image is displayed in a PictureBox. You passed in the wrong location of the orange cropping window. Here is the corrected code for you:

private void tsbRecortar_Click(object sender, EventArgs e){
  Point p = yourPictureBox.PointToClient(pbxSelection.PointToScreen(Point.Empty));
  Rectangle recorte = new Rectangle(p.X, p.Y, pbxSeleccion.Width, pbxSeleccion.Height);

  foto = recortarImagen(foto, recorte);
  pbxImagen.Image = foto;
}

我用 PointToClient PointToScreen 在这里,因为我认为这是做的最好的方式。然后,你可以改变你的图片框安全的容器,而无需修改code。如果您使用code像下面这样,它不是动态不够,当你想要把你的图片框在另一个容器:

I use PointToClient and PointToScreen here because I think it's the best way to do. You can then change the container of your pictureBox safely without having to modify the code. If you use the code like the following, it's not dynamically enough when you want to place your pictureBox in another container:

Rectangle recorte = new Rectangle(pbxSeleccion.X + yourPictureBox.Left,
                                  pbxSeleccion.Y + yourPictureBox.Top, 
                                  pbxSeleccion.Width, pbxSeleccion.Height);

注意:你也可以使用 RectangleToClient RectangleToScreen 是这样的:

NOTE: you can also use RectangleToClient and RectangleToScreen like this:

private void tsbRecortar_Click(object sender, EventArgs e){
   Rectangle recorte = yourPictureBox.RectangleToClient(pbxSeleccion.RectangleToScreen(pbxSeleccion.ClientRectangle));
   foto = recortarImagen(foto, recorte);
   pbxImagen.Image = foto;
}