C# 使用固定大小的可拖动画框裁剪图像
我正在做一个winforms项目,其中包括裁剪图像。我的目标是通过使用一个固定大小的可拖动picturebox控件来实现这一点,允许用户选择他们想要保留的区域 我的问题是当我裁剪图像时;这是可行的,但作物面积有一点偏移。以下是我得到的结果: 澄清一下,我不是说缩放,这是每个设计。请注意,橙色框主要聚焦于风暴眼,但裁剪后的图像并非如此 这是我的裁剪操作代码: 私有无效tsbRecortar_单击对象发送者,事件参数e { Rectangle recorte=新矩形pbxSeleccion.Location.X,pbxSeleccion.Location.Y,pbxSeleccion.Width,pbxSeleccion.Height; foto=recortarImagenfoto,recorte; pbxImagen.Image=foto; } 私有图像记录代理图像图像,矩形重现 { 尝试 { 位图位图=新的位图图像; 位图cropedBitmap=Bitmap.Clonerecuadro,Bitmap.PixelFormat; 返回图像位图; } 捕获异常 { MessageBox.Showex.Message,错误; 返回null; } } pbxSeleccion是可拖动的橙色矩形;它的父对象是pbxImage,我在窗体加载时将其重新设置为父对象 如您所见,我正在使用pbxSeleccion的坐标来定义作物区域的起点,但没有按预期工作。。。有时,我甚至会遇到内存不足的异常 我认为这与图片在父图片盒中的加载方式有关,与如何在引擎盖下处理边距有关,但我没有尝试修复它。。。只需更改偏移量的大小 搜索网页对我帮助很大,但对于这个问题,我似乎找不到答案。。。请随意指出我的代码的改进,我已经很久没有编码了,我是C和.NET的新手C# 使用固定大小的可拖动画框裁剪图像,c#,.net,winforms,image,crop,C#,.net,Winforms,Image,Crop,我正在做一个winforms项目,其中包括裁剪图像。我的目标是通过使用一个固定大小的可拖动picturebox控件来实现这一点,允许用户选择他们想要保留的区域 我的问题是当我裁剪图像时;这是可行的,但作物面积有一点偏移。以下是我得到的结果: 澄清一下,我不是说缩放,这是每个设计。请注意,橙色框主要聚焦于风暴眼,但裁剪后的图像并非如此 这是我的裁剪操作代码: 私有无效tsbRecortar_单击对象发送者,事件参数e { Rectangle recorte=新矩形pbxSeleccion.Lo
非常感谢您的帮助。干杯 假设您的原始图像显示在PictureBox中。您传入了错误的橙色裁剪窗口位置。以下是为您更正的代码:
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,因为我认为这是最好的方法。然后,您可以安全地更改pictureBox的容器,而无需修改代码。如果您使用以下代码,则当您要将pictureBox放置在另一个容器中时,动态性不够:
Rectangle recorte = new Rectangle(pbxSeleccion.X + yourPictureBox.Left,
pbxSeleccion.Y + yourPictureBox.Top,
pbxSeleccion.Width, pbxSeleccion.Height);
注意:您也可以像这样使用矩形到客户端和矩形到屏幕:
private void tsbRecortar_Click(object sender, EventArgs e){
Rectangle recorte = yourPictureBox.RectangleToClient(pbxSeleccion.RectangleToScreen(pbxSeleccion.ClientRectangle));
foto = recortarImagen(foto, recorte);
pbxImagen.Image = foto;
}
请尝试使用此代码在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;
}
输出屏幕
收割前
收割后
太好了,工作得很有魅力!感谢您抽出时间回复。我注意到部分错误来自我将pbxImagen中加载的图像的SizeMode设置为CenterImage。这是可以做到的,但一旦图像居中,我需要考虑左边距-我会处理它并更新这个。
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);
}
}