如何使用c#裁剪图像?
当前回答
在c#中裁剪图像非常简单。然而,做的东西,你将如何管理裁剪你的图像将会有点困难。
下面的示例是如何在c#中裁剪图像的方法。
var filename = @"c:\personal\images\horizon.png";
var img = Image.FromFile(filename);
var rect = new Rectangle(new Point(0, 0), img.Size);
var cloned = new Bitmap(img).Clone(rect, img.PixelFormat);
var bitmap = new Bitmap(cloned, new Size(50, 50));
cloned.Dispose();
其他回答
使用bmp.SetResolution(形象。HorizontalResolution, image .VerticalResolution);
这可能是必要的,即使你在这里实现了最佳答案 特别是如果你的图像真的很好,分辨率不是96.0
我的测试示例:
static Bitmap LoadImage()
{
return (Bitmap)Bitmap.FromFile( @"e:\Tests\d_bigImage.bmp" ); // here is large image 9222x9222 pixels and 95.96 dpi resolutions
}
static void TestBigImagePartDrawing()
{
using( var absentRectangleImage = LoadImage() )
{
using( var currentTile = new Bitmap( 256, 256 ) )
{
currentTile.SetResolution(absentRectangleImage.HorizontalResolution, absentRectangleImage.VerticalResolution);
using( var currentTileGraphics = Graphics.FromImage( currentTile ) )
{
currentTileGraphics.Clear( Color.Black );
var absentRectangleArea = new Rectangle( 3, 8963, 256, 256 );
currentTileGraphics.DrawImage( absentRectangleImage, 0, 0, absentRectangleArea, GraphicsUnit.Pixel );
}
currentTile.Save(@"e:\Tests\Tile.bmp");
}
}
}
这很简单:
创建一个裁剪大小的新位图对象。 使用图形。为新的位图创建一个图形对象。 使用DrawImage方法将图像绘制到具有负X和负Y坐标的位图上。
如果你在使用AForge。NET:
using(var croppedBitmap = new Crop(new Rectangle(10, 10, 10, 10)).Apply(bitmap))
{
// ...
}
这里有一个裁剪图像的简单例子
public Image Crop(string img, int width, int height, int x, int y)
{
try
{
Image image = Image.FromFile(img);
Bitmap bmp = new Bitmap(width, height, PixelFormat.Format24bppRgb);
bmp.SetResolution(80, 60);
Graphics gfx = Graphics.FromImage(bmp);
gfx.SmoothingMode = SmoothingMode.AntiAlias;
gfx.InterpolationMode = InterpolationMode.HighQualityBicubic;
gfx.PixelOffsetMode = PixelOffsetMode.HighQuality;
gfx.DrawImage(image, new Rectangle(0, 0, width, height), x, y, width, height, GraphicsUnit.Pixel);
// Dispose to free up resources
image.Dispose();
bmp.Dispose();
gfx.Dispose();
return bmp;
}
catch (Exception ex)
{
MessageBox.Show(ex.Message);
return null;
}
}
对于任何愿意使用“不安全”代码的人来说,您可以获得比标准System.Drawing.Graphics方法更好的性能,如果使用Bitmap.Clone()则更好。
请记住,32bpp是该方法支持的唯一格式。(其他格式可以工作,只要1像素存储为4字节)
我包含了两个版本,一个使用Span,它在裁剪到较小的图像时性能稍好。 如果裁剪到1000x1000的图像,它们的速度差不多。
如果感兴趣,基准在下面。
public static class BitmapExtension
{
unsafe public static Bitmap Crop(this Bitmap bitmap, int left, int top, int width, int height)
{
Bitmap cropped = new Bitmap(width, height);
BitmapData originalData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
BitmapData croppedData = cropped.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bitmap.PixelFormat);
int* srcPixel = (int*)originalData.Scan0 + (left + originalData.Width * top);
int nextLine = originalData.Width - width;
for (int y = 0, i = 0; y < height; y++, srcPixel += nextLine)
{
for (int x = 0; x < width; x++, i++, srcPixel++)
{
*((int*)croppedData.Scan0 + i) = *srcPixel;
}
}
bitmap.UnlockBits(originalData);
cropped.UnlockBits(croppedData);
return cropped;
}
unsafe public static Bitmap CropSmall(this Bitmap bitmap, int left, int top, int width, int height)
{
Bitmap cropped = new Bitmap(width, height);
BitmapData originalData = bitmap.LockBits(new System.Drawing.Rectangle(0, 0, bitmap.Width, bitmap.Height), ImageLockMode.ReadOnly, bitmap.PixelFormat);
BitmapData croppedData = cropped.LockBits(new System.Drawing.Rectangle(0, 0, width, height), ImageLockMode.WriteOnly, bitmap.PixelFormat);
Span<int> srcPixels = new Span<int>((void*)originalData.Scan0, originalData.Width * originalData.Height);
int nextLine = originalData.Width - width;
for (int y = 0, i = 0, s = left + originalData.Width * top; y < height; y++, s += nextLine)
{
for (int x = 0; x < width; x++, i++, s++)
{
*((int*)croppedData.Scan0 + i) = srcPixels[s];
}
}
bitmap.UnlockBits(originalData);
cropped.UnlockBits(croppedData);
return cropped;
}
}
裁剪3440x1440到1000x1000
Method | Ns |
---|---|
My Method | 1108 |
My Method(Span) | 1141 |
Graphics | 9975 |
Clone() | 21514 |
裁剪3440x1440到256x256
Method | Ns |
---|---|
My Method | 131 |
My Method(Span) | 95 |
Graphics | 1289 |
Clone() | 19680 |
裁剪3440x1440到1440x1440
Method | Ns |
---|---|
My Method | 2237 |
My Method(Span) | 2592 |
Graphics | 9999 |
Clone() | 25925 |
推荐文章
- Linq-to-Entities Join vs GroupJoin
- 为什么字符串类型的默认值是null而不是空字符串?
- 在list中获取不同值的列表
- 组合框:向项目添加文本和值(无绑定源)
- 如何为ASP.net/C#应用程序配置文件值中的值添加&号
- 从System.Drawing.Bitmap中加载WPF BitmapImage
- 如何找出一个文件存在于c# / .NET?
- 为什么更快地检查字典是否包含键,而不是捕捉异常,以防它不?
- [DataContract]的命名空间
- string. isnullorempty (string) vs. string. isnullowhitespace (string)
- 完全外部连接
- 在foreach循环中编辑字典值
- 如何在xml文档中引用泛型类和方法
- 使用System.IO.Compression在内存中创建ZIP存档
- 从HttpResponseMessage获取内容/消息