CSharp - 使用固定大小可以拖动picturebox裁剪图像

  显示原文与译文双语对照的内容
102 3

我正在处理一个包含裁剪图像的winforms项目。 我的目标是使用固定大小的可以拖动picturebox控件来实现这一目的,允许用户选择要保存的区域。

当我裁剪图像时,问题是:,但是裁剪区域偏移稍微小一点。 下面是我得到的结果:

Original imageCropped image

为了说明,我不是在讨论缩放,这是每个设计。 注意橙色框主要关注风暴的眼睛,但裁剪的图像并不是。

这是我用于裁剪操作的代码:


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;
 }
}

它的价格为draggable英镑,它的父元素为 pbxImage form form form form 。

可以看到,我使用 pbxSeleccion的坐标来定义裁剪区域的起点,但不能按预期的方式工作。 有时,我甚至会得到一个"内存不足"异常。

我认为这必须与如何在父voiceover中加载图像有关,如何处理"在引擎盖下",但没有尝试修复它。 仅更改偏移的大小。

搜索网站也帮助了我很多,但对于这个特定的问题,我找不到答案。 请随意指出我的代码改进,我没有为长时间编码,我是 C# 和. NET的新员工

任何帮助都非常感谢你。 cheers!

时间: 原作者:

109 4

假设你的原始图像显示在 PictureBox 中。 你在 orange cropping window 以下是你的更正代码:


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;
}

因为我认为这是最好的方法,所以我在这里使用 PointToClientPointToScreen 。 你可以在不修改代码的情况下安全地更改 PictureBox的容器。 如果使用如下代码,当你希望将 PictureBox 放置到另一个容器中时,它不是动态足够的:


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

注释: 你也可以像这样使用 RectangleToClientRectangleToScreen:


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

原作者:
63 4

尝试这里代码以在picturebox中裁剪图像


 public static Image Fit2PictureBox(this Image image, PictureBox picBox)
 {
 Bitmap bmp = null;
 Graphics g;

//Scale:
 double scaleY = (double)image.Width/picBox.Width;
 double scaleX = (double)image.Height/picBox.Height;
 double scale = scaleY <scaleX? scaleX : scaleY;

//Create new bitmap:
 bmp = new Bitmap(
 (int)((double)image.Width/scale),
 (int)((double)image.Height/scale));

//Set resolution of the new image:
 bmp.SetResolution(
 image.HorizontalResolution,
 image.VerticalResolution);

//Create graphics:
 g = Graphics.FromImage(bmp);

//Set interpolation mode:
 g.InterpolationMode = InterpolationMode.HighQualityBicubic;

//Draw the new image:
 g.DrawImage(
 image,
 new Rectangle(//Ziel
 0, 0,
 bmp.Width, bmp.Height),
 new Rectangle(//Quelle
 0, 0,
 image.Width, image.Height),
 GraphicsUnit.Pixel);

//Release the resources of the graphics:
 g.Dispose();

//Release the resources of the origin image:
 image.Dispose();

 return bmp;
 } 

 public static Image Crop(this Image image, Rectangle selection)
 {
 Bitmap bmp = image as Bitmap;

//Check if it is a bitmap:
 if (bmp == null)
 throw new ArgumentException("Kein gültiges Bild (Bitmap)");

//Crop the image:
 Bitmap cropBmp = bmp.Clone(selection, bmp.PixelFormat);

//Release the resources:
 image.Dispose();

 return cropBmp;
 }

将鼠标事件的下面代码写入 PictureBox


 private void pictureBox1_MouseDown(object sender, MouseEventArgs e)
 {
 if (e.Button == MouseButtons.Left)
 {
 _selecting = true;
 _selection = new Rectangle(new Point(e.X, e.Y), new Size());
 }
 }

 private void pictureBox1_MouseUp(object sender, MouseEventArgs e)
 {
 if (e.Button == MouseButtons.Left && _selecting)
 {
//Create cropped image:
 try
 {
 Image img = pictureBox1.Image.Crop(_selection);


//Fit image to the picturebox:
 pictureBox1.Image = img.Fit2PictureBox(pictureBox1);
 }
 catch { }
 _selecting = false;
 }
 }

 private void pictureBox1_MouseMove(object sender, MouseEventArgs e)
 {
//Update the actual size of the selection:
 if (_selecting)
 {
 _selection.Width = e.X - _selection.X;
 _selection.Height = e.Y - _selection.Y;

//Redraw the picturebox:
 pictureBox1.Refresh();
 }
 }

 private void pictureBox1_Paint(object sender, PaintEventArgs e)
 {
 if (_selecting)
 {
//Draw a rectangle displaying the current selection
 Pen pen = Pens.LightSkyBlue;
 e.Graphics.DrawRectangle(pen, _selection);
 }
 }

输出屏幕

  1. 裁剪前

enter image description here

  1. 裁剪后

enter image description here

原作者:
...