如何使用c#裁剪图像?
当前回答
对于任何愿意使用“不安全”代码的人来说,您可以获得比标准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 |
其他回答
你可以使用[图形。使用DrawImage][1]将裁剪图像从位图绘制到图形对象上。
Rectangle cropRect = new Rectangle(...);
using (Bitmap src = Image.FromFile("") as Bitmap)
{
using (Bitmap target = new Bitmap(cropRect.Width, cropRect.Height))
{
using (Graphics g = Graphics.FromImage(target))
{
g.DrawImage(src, new Rectangle(0, 0, target.Width, target.Height),
cropRect,
GraphicsUnit.Pixel);
}
}
}
这里有一个裁剪图像的简单例子
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;
}
}
假设您想要获取一个图像文件(JPEG、BMP、TIFF等)并将其裁剪,然后将其保存为一个较小的图像文件,我建议使用具有. net API的第三方工具。以下是我喜欢的一些流行的说法:
LeadTools Accusoft珀加索斯 雪地成像SDK
有一个开源的c#包装器,托管在Codeplex上,叫做Web Image裁剪
注册控件
<%@注册程序集="CS.Web.UI. "CropImage CS.Web“Namespace =”。UI" TagPrefix="cs" %>
调整
<asp:Image ID="Image1" runat="server" ImageUrl="images/328.jpg" />
<cs:CropImage ID="wci1" runat="server" Image="Image1"
X="10" Y="10" X2="50" Y2="50" />
在代码后面裁剪-当按钮点击时调用裁剪方法为例;
wci1.Crop (Server.MapPath(“图像/ sample1.jpg”));
查看这个链接:http://www.switchonthecode.com/tutorials/csharp-tutorial-image-editing-saving-cropping-and-resizing
private static Image cropImage(Image img, Rectangle cropArea)
{
Bitmap bmpImage = new Bitmap(img);
return bmpImage.Clone(cropArea, bmpImage.PixelFormat);
}
推荐文章
- 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获取内容/消息