dotnet/wpf · error · InvalidOperationException
SR.Image_OnlyOrthogonal
Error message
SR.Image_OnlyOrthogonal
What it means
TransformedBitmap supports only orthogonal transforms (90/180/270-degree rotations, flips, and composites whose matrix stays axis-aligned), verified by CheckTransform. Any non-orthogonal transform — arbitrary-angle rotation, skew, translation matrix — throws InvalidOperationException with SR.Image_OnlyOrthogonal.
Solutions
- Use only RotateTransform with angles that are multiples of 90 or flip/scale-by-±1 transforms
- For arbitrary angles, render the source through a DrawingVisual with the transform into a RenderTargetBitmap
- Snap the requested angle to the nearest 90-degree multiple before constructing the bitmap
Example fix
// before
var tb = new TransformedBitmap(source, new RotateTransform(45));
// after
var dv = new DrawingVisual();
using (var ctx = dv.RenderOpen())
{
ctx.PushTransform(new RotateTransform(45, source.Width/2, source.Height/2));
ctx.DrawImage(source, new Rect(0, 0, source.Width, source.Height));
}
var rtb = new RenderTargetBitmap((int)source.Width*2, (int)source.Height*2, 96, 96, PixelFormats.Pbgra32);
rtb.Render(dv); Defensive patterns
Strategy: validation
Validate before calling
static bool IsOrthogonal(Transform t)
{
var m = t.Value;
return (m.M11, m.M12, m.M21, m.M22) is (1,0,0,1) or (-1,0,0,-1)
or (0,1,-1,0) or (0,-1,1,0);
} Type guard
static bool IsOrthogonalTransform(Transform t) =>
t is RotateTransform r && r.Angle % 90 == 0 ||
t is ScaleTransform s && Math.Abs(s.ScaleX) == 1 && Math.Abs(s.ScaleY) == 1 ||
t is TransformGroup g && g.Children.All(IsOrthogonalTransform); Try / catch
try { var tb = new TransformedBitmap(source, transform); }
catch (InvalidOperationException ex) when (ex.Message.Contains("orthogonal"))
{ /* render via DrawingVisual + RenderTargetBitmap instead */ } Prevention
- Restrict transform inputs to 0/90/180/270 rotations and flips
- Inspect transform.Value for axis-aligned matrix entries before use
- Use RenderTargetBitmap + DrawingVisual for arbitrary-angle rendering
When it happens
Trigger: new TransformedBitmap(source, new RotateTransform(45)) or any transform whose Value matrix has non-axis-aligned M11/M12/M21/M22 entries, including a TransformGroup whose combined matrix is not orthogonal.
Common situations: Rotating images by arbitrary angles (30, 45 degrees); applying skew transforms for visual effects; stacking multiple transforms in a TransformGroup where the composite loses orthogonality.
Understand the failure class
Background: "Must be a positive integer", "Invalid value", "Unsupported": the invalid-argument-value error family, when a library rejects the value you pass — this error's family across 35 libraries.
Related errors
- SR.Image_NoArgument (Transform)
- Cannot countersign an unsigned package.
- Cannot read Page properties because it is not in a tree…
- Cannot sign read-only file.
- Exception of type 'System.InvalidOperationException' was…
AI-assisted analysis of dotnet/wpf@81131a70a4 (2026-09-14).
Data as JSON: /api/errors/1cf261f0096655ba.
Report an issue: GitHub.
Appendix: source
Thrown at src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Imaging/TransformedBitmap.cs:41
/// <summary>
/// Construct a TransformedBitmap with the given newTransform
/// </summary>
/// <param name="source">BitmapSource to apply to the newTransform to</param>
/// <param name="newTransform">Transform to apply to the bitmap</param>
public TransformedBitmap(BitmapSource source, Transform newTransform)
: base(true) // Use base class virtuals
{
ArgumentNullException.ThrowIfNull(source);
if (newTransform == null)
{
throw new InvalidOperationException(SR.Format(SR.Image_NoArgument, "Transform"));
}
if (!CheckTransform(newTransform))
{
throw new InvalidOperationException(SR.Image_OnlyOrthogonal);
}
_bitmapInit.BeginInit();
Source = source;
Transform = newTransform;
_bitmapInit.EndInit();
FinalizeCreation();
}
// ISupportInitialize
/// <summary>
/// Prepare the bitmap to accept initialize paramters.
/// </summary>
public void BeginInit()
{View on GitHub (pinned to 81131a70a4)