如何使用C#裁剪图像?
我怎样才能写一个应用程序,将在C#中裁剪图像?
您可以使用Graphics.DrawImage
从位图绘制裁剪图像到图形对象。
Rectangle cropRect = new Rectangle(...); Bitmap src = Image.FromFile(fileName) as Bitmap; 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); }
看看这个链接: 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); }
比接受的答案更简单的是:
public static Bitmap cropAtRect(this Bitmap b, Rectangle r) { Bitmap nb = new Bitmap(r.Width, r.Height); Graphics g = Graphics.FromImage(nb); g.DrawImage(b, -rX, -rY); return nb; }
避免了最简单答案的“ 内存不足 ”异常风险。
编辑 :我觉得这与由Bitmap.Save
或Paint.exe保存的Bitmap.Save
罚款,但与例如Paint Shop Pro 6保存的PNG失败 – 内容被取代。 GraphicsUnit.Pixel
给出了不同的错误结果。 也许这些失败的PNG是错误的。
使用bmp.SetResolution(image.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"); } } }
这很容易:
- 用裁剪的大小创建一个新的
Bitmap
对象。 - 使用
Graphics.FromImage
为新的位图创建一个Graphics
对象。 - 使用
DrawImage
方法将图像绘制到具有负X和Y坐标的位图上。
下面是裁剪图像的简单示例
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; } }
如果您正在使用AForge.NET :
using(var croppedBitmap = new Crop(new Rectangle(10, 10, 10, 10)).Apply(bitmap)) { // ... }
在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();
有一个C#包装器,它是开源的,在Codeplex上被称为Web Image Cropping
注册控件
<%@ Register Assembly="CS.Web.UI.CropImage" Namespace="CS.Web.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("images/sample1.jpg"));
只有这个样本工作没有问题:
var crop = new Rectangle(0, y, bitmap.Width, h); var bmp = new Bitmap(bitmap.Width, h); var tempfile = Application.StartupPath+"\\"+"TEMP"+"\\"+Path.GetRandomFileName(); using (var gr = Graphics.FromImage(bmp)) { try { var dest = new Rectangle(0, 0, bitmap.Width, h); gr.DrawImage(image,dest , crop, GraphicsUnit.Point); bmp.Save(tempfile,ImageFormat.Jpeg); bmp.Dispose(); } catch (Exception) { } }
这是另一种方式。 在我的情况下,我有:
- 2个数字上传控件(称为LeftMargin和TopMargin)
- 1图片框(pictureBox1)
- 1个按钮,我称之为生成
- 在C:\ imagenes \ myImage.gif上有1张图片
在按钮里面我有这个代码:
Image myImage = Image.FromFile(@"C:\imagenes\myImage.gif"); Bitmap croppedBitmap = new Bitmap(myImage); croppedBitmap = croppedBitmap.Clone( new Rectangle( (int)LeftMargin.Value, (int)TopMargin.Value, myImage.Width - (int)LeftMargin.Value, myImage.Height - (int)TopMargin.Value), System.Drawing.Imaging.PixelFormat.DontCare); pictureBox1.Image = croppedBitmap;
我在Visual Studio 2012中使用C#尝试了它。 我从这个页面找到了这个解决方案
这里是在github上的工作演示
https://github.com/SystematixIndore/Crop-SaveImageInCSharp
<%@ Page Language="C#" AutoEventWireup="true" CodeBehind="WebForm1.aspx.cs" Inherits="WebApplication1.WebForm1" %> <!DOCTYPE html> <html xmlns="http://www.w3.org/1999/xhtml"> <head runat="server"> <title></title> <link href="css/jquery.Jcrop.css" rel="stylesheet" type="text/css" /> <script type="text/javascript" src="http://ajax.googleapis.com/ajax/libs/jquery/1.3/jquery.min.js"></script> <script type="text/javascript" src="js/jquery.Jcrop.js"></script> </head> <body> <form id="form2" runat="server"> <div> <asp:Panel ID="pnlUpload" runat="server"> <asp:FileUpload ID="Upload" runat="server" /> <br /> <asp:Button ID="btnUpload" runat="server" OnClick="btnUpload_Click" Text="Upload" /> <asp:Label ID="lblError" runat="server" Visible="false" /> </asp:Panel> <asp:Panel ID="pnlCrop" runat="server" Visible="false"> <asp:Image ID="imgCrop" runat="server" /> <br /> <asp:HiddenField ID="X" runat="server" /> <asp:HiddenField ID="Y" runat="server" /> <asp:HiddenField ID="W" runat="server" /> <asp:HiddenField ID="H" runat="server" /> <asp:Button ID="btnCrop" runat="server" Text="Crop" OnClick="btnCrop_Click" /> </asp:Panel> <asp:Panel ID="pnlCropped" runat="server" Visible="false"> <asp:Image ID="imgCropped" runat="server" /> </asp:Panel> </div> </form> <script type="text/javascript"> jQuery(document).ready(function() { jQuery('#imgCrop').Jcrop({ onSelect: storeCoords }); }); function storeCoords(c) { jQuery('#X').val(cx); jQuery('#Y').val(cy); jQuery('#W').val(cw); jQuery('#H').val(ch); }; </script> </body> </html>
用于上传和裁剪的C#代码逻辑。
using System; using System.Collections.Generic; using System.Linq; using System.Web; using System.Web.UI; using System.Web.UI.WebControls; using System.IO; using SD = System.Drawing; using System.Drawing.Imaging; using System.Drawing.Drawing2D; namespace WebApplication1 { public partial class WebForm1 : System.Web.UI.Page { String path = HttpContext.Current.Request.PhysicalApplicationPath + "images\\"; protected void Page_Load(object sender, EventArgs e) { } protected void btnUpload_Click(object sender, EventArgs e) { Boolean FileOK = false; Boolean FileSaved = false; if (Upload.HasFile) { Session["WorkingImage"] = Upload.FileName; String FileExtension = Path.GetExtension(Session["WorkingImage"].ToString()).ToLower(); String[] allowedExtensions = { ".png", ".jpeg", ".jpg", ".gif" }; for (int i = 0; i < allowedExtensions.Length; i++) { if (FileExtension == allowedExtensions[i]) { FileOK = true; } } } if (FileOK) { try { Upload.PostedFile.SaveAs(path + Session["WorkingImage"]); FileSaved = true; } catch (Exception ex) { lblError.Text = "File could not be uploaded." + ex.Message.ToString(); lblError.Visible = true; FileSaved = false; } } else { lblError.Text = "Cannot accept files of this type."; lblError.Visible = true; } if (FileSaved) { pnlUpload.Visible = false; pnlCrop.Visible = true; imgCrop.ImageUrl = "images/" + Session["WorkingImage"].ToString(); } } protected void btnCrop_Click(object sender, EventArgs e) { string ImageName = Session["WorkingImage"].ToString(); int w = Convert.ToInt32(W.Value); int h = Convert.ToInt32(H.Value); int x = Convert.ToInt32(X.Value); int y = Convert.ToInt32(Y.Value); byte[] CropImage = Crop(path + ImageName, w, h, x, y); using (MemoryStream ms = new MemoryStream(CropImage, 0, CropImage.Length)) { ms.Write(CropImage, 0, CropImage.Length); using (SD.Image CroppedImage = SD.Image.FromStream(ms, true)) { string SaveTo = path + "crop" + ImageName; CroppedImage.Save(SaveTo, CroppedImage.RawFormat); pnlCrop.Visible = false; pnlCropped.Visible = true; imgCropped.ImageUrl = "images/crop" + ImageName; } } } static byte[] Crop(string Img, int Width, int Height, int X, int Y) { try { using (SD.Image OriginalImage = SD.Image.FromFile(Img)) { using (SD.Bitmap bmp = new SD.Bitmap(Width, Height)) { bmp.SetResolution(OriginalImage.HorizontalResolution, OriginalImage.VerticalResolution); using (SD.Graphics Graphic = SD.Graphics.FromImage(bmp)) { Graphic.SmoothingMode = SmoothingMode.AntiAlias; Graphic.InterpolationMode = InterpolationMode.HighQualityBicubic; Graphic.PixelOffsetMode = PixelOffsetMode.HighQuality; Graphic.DrawImage(OriginalImage, new SD.Rectangle(0, 0, Width, Height), X, Y, Width, Height, SD.GraphicsUnit.Pixel); MemoryStream ms = new MemoryStream(); bmp.Save(ms, OriginalImage.RawFormat); return ms.GetBuffer(); } } } } catch (Exception Ex) { throw (Ex); } } } }
我正在寻找一个简单而快速的功能,没有额外的库文件来完成这项工作。 我试过尼克斯解决方案 ,但是我需要29.4秒才能“提取”1195张图册文件。 所以后来我以这种方式管理,需要243秒才能完成同样的工作。 也许这会有所帮助。
// content of the Texture class public class Texture { //name of the texture public string name { get; set; } //x position of the texture in the atlas image public int x { get; set; } //y position of the texture in the atlas image public int y { get; set; } //width of the texture in the atlas image public int width { get; set; } //height of the texture in the atlas image public int height { get; set; } } Bitmap atlasImage = new Bitmap(@"C:\somepicture.png"); PixelFormat pixelFormat = atlasImage.PixelFormat; foreach (Texture t in textureList) { try { CroppedImage = new Bitmap(t.width, t.height, pixelFormat); // copy pixels over to avoid antialiasing or any other side effects of drawing // the subimages to the output image using Graphics for (int x = 0; x < t.width; x++) for (int y = 0; y < t.height; y++) CroppedImage.SetPixel(x, y, atlasImage.GetPixel(tx + x, ty + y)); CroppedImage.Save(Path.Combine(workingFolder, t.name + ".png"), ImageFormat.Png); } catch (Exception ex) { // handle the exception } }
假设你的意思是你想要一个图像文件(JPEG,BMP,TIFF等)和裁剪,然后将其保存为一个较小的图像文件,我建议使用具有.NET API的第三方工具。 这里有一些我喜欢的流行的:
LEADTOOLS
Accusoft Pegasus大雪 影像SDK