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

  1. Use only RotateTransform with angles that are multiples of 90 or flip/scale-by-±1 transforms
  2. For arbitrary angles, render the source through a DrawingVisual with the transform into a RenderTargetBitmap
  3. 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

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


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)