Load the image, call Crop(x, y, width, height) with the rectangle to keep, and save. Coordinates start at the top-left corner. The program below crops NASA’s “Blue Marble” photograph (4579×4579, public domain) to a rectangle, and a public test photo from a phone to a centered square.
dotnet new console -o CropImage && cd CropImage dotnet add package RecursiveAI.OneImage --version 1.10.4 curl -L -o photo.jpg \ https://images-assets.nasa.gov/image/as17-148-22727/as17-148-22727~orig.jpg repo=https://raw.githubusercontent.com/recurser/exif-orientation-examples curl -L -o phone.jpg $repo/master/Portrait_6.jpg
OneImage needs the .NET 10 SDK. Put this in Program.cs and run dotnet run:
using OneImage; Image photo = Image.Load("photo.jpg"); // reads the headers only // The 1200x800 region whose top-left corner is at (100, 80). Image rect = photo.Crop(100, 80, 1200, 800); rect.Save("crop.jpg"); // The largest centered square of a portrait phone photo. Image phone = Image.Load("phone.jpg"); // 1200x1800 once upright int side = Math.Min(phone.Width, phone.Height); int x = (phone.Width - side) / 2, y = (phone.Height - side) / 2; Image square = phone.Crop(x, y, side, side); square.Save("square.jpg"); Console.WriteLine($"crop.jpg: {rect.Width}x{rect.Height}"); Console.WriteLine($"square.jpg: {square.Width}x{square.Height}"); try { photo.Crop(4000, 4000, 1000, 1000); // runs past the right and bottom edges } catch (ArgumentOutOfRangeException ex) { Console.WriteLine(ex.Message.Split('\n')[0]); }
crop.jpg: 1200x800 square.jpg: 1200x1200 Crop rectangle lies outside the image. (Parameter 'rect')
The rectangle must lie inside the image, so clamp coordinates that come from users. Tiles outside the rectangle are never decoded. Width and Height are the upright size: Load applies a phone photo’s EXIF orientation first, so crop coordinates from a browser, which also shows photos upright, line up (EXIF orientation).
Crop to an aspect ratio and size
For banners and cards you usually want a fixed output size. Resize with Fit.Cover crops to the aspect ratio and resizes in one step, and anchor: chooses which part survives:
using OneImage; Image photo = Image.Load("photo.jpg"); // 16:9 at 1280x720: the center, the top, or the busiest area. photo.Resize(width: 1280, height: 720, fit: Fit.Cover).Save("wide-center.jpg"); photo.Resize(width: 1280, height: 720, fit: Fit.Cover, anchor: Anchor.Top) .Save("wide-top.jpg"); photo.Resize(width: 1280, height: 720, fit: Fit.Cover, anchor: Anchor.Smart) .Save("wide-smart.jpg"); foreach (string file in new[] { "wide-center.jpg", "wide-top.jpg", "wide-smart.jpg" }) { ImageInfo info = Image.Identify(file); Console.WriteLine($"{file}: {info.Width}x{info.Height}"); }
wide-center.jpg: 1280x720 wide-top.jpg: 1280x720 wide-smart.jpg: 1280x720
Anchor.Smart picks the area with the most detail. To remove a uniform border, such as the white margin of a scan, call Trim() instead of computing a rectangle.
Limits
- Out-of-range rectangles throw
ArgumentOutOfRangeExceptionat theCropcall. Clamp first. - A crop of a JPEG is re-encoded, so it isn’t lossless. Save as PNG to keep the cropped pixels exactly.
- Animations: the rectangle applies to every frame (Resize an animated GIF).
To crop a user-picked square from an upload, combine this with Resize uploaded images in ASP.NET Core. Every geometry operation is in the guide.