{"record":{"id":"1cf261f0096655ba","repo":"dotnet/wpf","slug":"sr-image-onlyorthogonal","errorCode":null,"errorMessage":"SR.Image_OnlyOrthogonal","messagePattern":"SR\\.Image_OnlyOrthogonal","errorType":"exception","errorClass":"InvalidOperationException","httpStatus":null,"severity":"error","filePath":"src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Imaging/TransformedBitmap.cs","lineNumber":41,"sourceCode":"\n        /// <summary>\n        /// Construct a TransformedBitmap with the given newTransform\n        /// </summary>\n        /// <param name=\"source\">BitmapSource to apply to the newTransform to</param>\n        /// <param name=\"newTransform\">Transform to apply to the bitmap</param>\n        public TransformedBitmap(BitmapSource source, Transform newTransform)\n            : base(true) // Use base class virtuals\n        {\n            ArgumentNullException.ThrowIfNull(source);\n\n            if (newTransform == null)\n            {\n                throw new InvalidOperationException(SR.Format(SR.Image_NoArgument, \"Transform\"));\n            }\n\n            if (!CheckTransform(newTransform))\n            {\n                throw new InvalidOperationException(SR.Image_OnlyOrthogonal);\n            }\n\n            _bitmapInit.BeginInit();\n\n            Source = source;\n            Transform = newTransform;\n\n            _bitmapInit.EndInit();\n            FinalizeCreation();\n        }\n\n        // ISupportInitialize\n\n        /// <summary>\n        /// Prepare the bitmap to accept initialize paramters.\n        /// </summary>\n        public void BeginInit()\n        {","sourceCodeStart":23,"sourceCodeEnd":59,"githubUrl":"https://github.com/dotnet/wpf/blob/81131a70a4c573cd62748a5c36908fc4d662daa9/src/Microsoft.DotNet.Wpf/src/PresentationCore/System/Windows/Media/Imaging/TransformedBitmap.cs#L23-L59","documentation":"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.","triggerScenarios":"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.","commonSituations":"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.","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"],"exampleFix":"// before\nvar tb = new TransformedBitmap(source, new RotateTransform(45));\n// after\nvar dv = new DrawingVisual();\nusing (var ctx = dv.RenderOpen())\n{\n    ctx.PushTransform(new RotateTransform(45, source.Width/2, source.Height/2));\n    ctx.DrawImage(source, new Rect(0, 0, source.Width, source.Height));\n}\nvar rtb = new RenderTargetBitmap((int)source.Width*2, (int)source.Height*2, 96, 96, PixelFormats.Pbgra32);\nrtb.Render(dv);","handlingStrategy":"validation","validationCode":"static bool IsOrthogonal(Transform t)\n{\n    var m = t.Value;\n    return (m.M11, m.M12, m.M21, m.M22) is (1,0,0,1) or (-1,0,0,-1)\n                                     or (0,1,-1,0) or (0,-1,1,0);\n}","typeGuard":"static bool IsOrthogonalTransform(Transform t) =>\n    t is RotateTransform r && r.Angle % 90 == 0 ||\n    t is ScaleTransform s && Math.Abs(s.ScaleX) == 1 && Math.Abs(s.ScaleY) == 1 ||\n    t is TransformGroup g && g.Children.All(IsOrthogonalTransform);","tryCatchPattern":"try { var tb = new TransformedBitmap(source, transform); }\ncatch (InvalidOperationException ex) when (ex.Message.Contains(\"orthogonal\"))\n{ /* render via DrawingVisual + RenderTargetBitmap instead */ }","preventionTips":["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"],"tags":["wpf","transform","orthogonal","invalidoperationexception"],"backgroundTag":"invalid-argument-value","analyzedSha":"81131a70a4c573cd62748a5c36908fc4d662daa9","analyzedAt":"2026-09-14T10:12:48.479Z","contentChangedAt":"2026-09-14T10:12:48.479Z","schemaVersion":2},"datasetVersion":"2026-09-21T21:30:21.729Z"}