Rotating images by an arbitrary angle with a transparent background is a frequent requirement for galleries, dashboards, and design tools in .NET. Aspose.Imaging for .NET provides a direct API to load an image, rotate it by a custom angle, and save to a format that supports transparency.
Complete Example
// File: Program.cs
// Requires NuGet: Aspose.Imaging
using System;
using System.Collections.Generic;
using System.IO;
using Aspose.Imaging;
using Aspose.Imaging.ImageOptions;
namespace RotateTransparentDemo
{
public static class Program
{
public static int Main(string[] args)
{
try
{
if (args.Length == 0)
{
// Single-file demo paths. Replace with your own files or pass CLI args.
var input = "input.png"; // source can be PNG, JPG, etc.
var output = "rotated-output.png"; // must be PNG to preserve transparency
RotateSingle(input, output, angleDegrees: 17f, expandCanvas: true);
Console.WriteLine($"Saved: {output}");
return 0;
}
// CLI:
// 1) Single file:
// RotateTransparentDemo.exe <inputPath> <outputPath> <angleDegrees> [expandCanvas:true|false]
//
// 2) Batch folder:
// RotateTransparentDemo.exe --batch <inputDir> <outputDir> <angleDegrees> [expandCanvas:true|false]
if (args[0].Equals("--batch", StringComparison.OrdinalIgnoreCase))
{
if (args.Length < 4)
{
Console.Error.WriteLine("Usage: --batch <inputDir> <outputDir> <angleDegrees> [expandCanvas:true|false]");
return 2;
}
var inputDir = args[1];
var outputDir = args[2];
var angle = float.Parse(args[3]);
var expandCanvas = args.Length >= 5 ? bool.Parse(args[4]) : true;
BatchRotate(inputDir, outputDir, angle, expandCanvas);
Console.WriteLine($"Batch complete. Output in: {outputDir}");
return 0;
}
else
{
if (args.Length < 3)
{
Console.Error.WriteLine("Usage: <inputPath> <outputPath> <angleDegrees> [expandCanvas:true|false]");
return 2;
}
var inputPath = args[0];
var outputPath = args[1];
var angle = float.Parse(args[2]);
var expandCanvas = args.Length >= 4 ? bool.Parse(args[3]) : true;
RotateSingle(inputPath, outputPath, angle, expandCanvas);
Console.WriteLine($"Saved: {outputPath}");
return 0;
}
}
catch (Exception ex)
{
Console.Error.WriteLine("Error: " + ex.Message);
return 1;
}
}
/// <summary>
/// Rotates a single image by an arbitrary angle and preserves transparency in the output PNG.
/// </summary>
private static void RotateSingle(string inputPath, string outputPath, float angleDegrees, bool expandCanvas)
{
if (!File.Exists(inputPath))
throw new FileNotFoundException("Input image not found.", inputPath);
// If you expect large images or batches, you can enable disk cache to reduce RAM pressure:
// Aspose.Imaging.Cache.CacheType = Aspose.Imaging.Cache.CacheType.CacheOnDisk;
// Aspose.Imaging.Cache.CacheFolder = Path.GetFullPath(".imaging-cache");
// Aspose.Imaging.Cache.CacheSize = 512L * 1024 * 1024; // 512 MB
using (var image = Image.Load(inputPath))
{
// Raster operations are available on RasterImage
if (image is not RasterImage raster)
throw new InvalidOperationException("Loaded image is not a raster image.");
// Rotate by an arbitrary angle. Set expandCanvas to true to avoid clipping.
// Color.Transparent keeps the background transparent for alpha-capable formats.
raster.Rotate(angleDegrees, expandCanvas, Color.Transparent);
// Save as PNG to preserve alpha channel
var pngOptions = new PngOptions
{
// Most cases do not need explicit color type; leaving defaults preserves alpha.
// Uncomment if you want to force RGBA:
// ColorType = Aspose.Imaging.FileFormats.Png.PngColorType.TruecolorWithAlpha
};
// Ensure output directory exists
Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(outputPath)) ?? ".");
raster.Save(outputPath, pngOptions);
}
}
/// <summary>
/// Rotates all supported images in a folder and writes PNG outputs with transparency preserved.
/// </summary>
private static void BatchRotate(string inputDir, string outputDir, float angleDegrees, bool expandCanvas)
{
if (!Directory.Exists(inputDir))
throw new DirectoryNotFoundException("Input directory not found: " + inputDir);
Directory.CreateDirectory(outputDir);
// Common raster extensions. Adjust as needed.
var extensions = new HashSet<string>(StringComparer.OrdinalIgnoreCase)
{
".png", ".jpg", ".jpeg", ".bmp", ".gif", ".tif", ".tiff", ".webp"
};
var files = Directory.GetFiles(inputDir, "*.*", SearchOption.AllDirectories);
foreach (var file in files)
{
var ext = Path.GetExtension(file);
if (!extensions.Contains(ext))
continue;
var rel = Path.GetRelativePath(inputDir, file);
var relBase = Path.ChangeExtension(rel, ".png"); // output is PNG to keep transparency
var outPath = Path.Combine(outputDir, relBase);
Directory.CreateDirectory(Path.GetDirectoryName(Path.GetFullPath(outPath)) ?? ".");
try
{
RotateSingle(file, outPath, angleDegrees, expandCanvas);
Console.WriteLine($"OK {rel} -> {relBase}");
}
catch (Exception ex)
{
Console.WriteLine($"ERR {rel}: {ex.Message}");
}
}
}
}
}
How it works
Image.Load
opens the source. The code checks and casts toRasterImage
for raster operations.raster.Rotate(angle, expandCanvas, Color.Transparent)
rotates by any degree value.- Saving with
PngOptions
preserves transparency. - Batch mode walks a directory tree, rotates supported formats, and writes PNGs.
Step-by-step guide
1) Load the image
Use Image.Load
to open the source file. Cast to RasterImage
if you need raster-specific members.
using (var image = (RasterImage)Image.Load(inputPath))
{
// work with the image here
}
2) Rotate by any angle
Call Rotate(angle, expandCanvas, backgroundColor)
.
angle
is in degreesexpandCanvas = true
avoids clipping by resizing the canvas to fit the rotated boundsColor.Transparent
keeps the background transparent if the output format supports alpha
image.Rotate(17, true, Color.Transparent);
3) Save to a format that supports transparency
PNG supports transparency. Use PngOptions
to save the rotated output with the alpha channel preserved.
image.Save(outputPath, new PngOptions());
Practical options
- Avoid clipping: set
expandCanvas = true
when rotating by non-right angles - Opaque backgrounds: pass a solid
Color
instead ofColor.Transparent
if you want a filled background - Lossless output: prefer PNG for UIs, logos, and overlays that need crisp edges and transparency
- Photography: if you do not need transparency, saving as JPEG can reduce file size
Common pitfalls and fixes
Transparent background lost Save with
PngOptions
or another format that supports alpha. JPEG does not support transparency.Parts of the image are missing after rotation Use
expandCanvas = true
to grow the canvas so the rotated content fits.Jagged edges after rotation Rotation uses library defaults. If your source is low resolution, consider resizing the input to a higher resolution before rotating, then downscale after saving to reduce visible artifacts.
Memory and large images Dispose images promptly and avoid loading many large files at once. Configure disk caching for big batches if needed.
Mini checklist
- Load with
Image.Load
- Rotate with
image.Rotate(angle, true, Color.Transparent)
- Save with
new PngOptions()
for transparency - Use solid background if transparency is not required
- Validate output visually for key assets
FAQ
Which formats keep transparency after rotation PNG and other alpha-capable formats. JPEG does not retain transparency.
How do I rotate without enlarging the canvas
Pass expandCanvas = false
. Content outside the original bounds will be clipped.
Can I rotate by any angle Yes. The angle parameter accepts any numeric degree value.
More in this category
- Optimizing Animated GIFs in .NET using Aspose.Imaging
- Optimize Multi-Page TIFFs for Archival in .NET with Aspose
- Comparing Lossy vs. Lossless Image Compression in .NET using Aspose.Imaging
- Converting TIFF to PDF in C# with Aspose.Imaging
- Cropping Product Images for E-Commerce Platforms using Aspose.Imaging for .NET