【问题标题】:WPF: How to rotate a BitmapSource by any angleWPF:如何将 BitmapSource 旋转任意角度
【发布时间】:2016-02-28 02:28:42
【问题描述】:

好的,我试过了:

TransformedBitmap tbm = new TransformedBitmap(myBitmapSource, new RotateTransform(angle));
return tbm;

但这不适用于除 90 度的倍数以外的角度。

新我尝试使用 RenderTargetBitmap:

  var image = new Canvas();
  image.Width = myBitmapSource.PixelWidth;
  image.Height = myBitmapSource.PixelHeight;
  image.Background = new ImageBrush(myBitmapSource);
  image.RenderTransform = new RotateTransform(angle);
  RenderTargetBitmap rtb = new RenderTargetBitmap(myBitmapSource.PixelWidth, myBitmapSource.PixelHeight, myBitmapSource.DpiX, myBitmapSource.DpiY, myBitmapSource.Format);
  rtb.Render(image);
  return rtb;

但这给了我:

"The calling thread must be STA, because many UI components require this."

这在没有 GUI 的服务中运行。

谁能给我一个工作代码示例,说明如何在 WPF(没有 GUI)中将 BitmapSource 旋转任意角度?

更新:

为功能请求投票:http://visualstudio.uservoice.com/forums/121579-visual-studio-2015/suggestions/10870098-allow-rotation-of-bitmapsource-by-any-angle

【问题讨论】:

  • 如果您在运行代码的线程上调用SetApartmentState(ApartmentState.STA),它应该可以工作。但是请注意,您必须以某种方式计算 resultimg 位图的正确大小。否则部分源位图可能会被截断。此外,您可能希望围绕图像中心旋转,因此您应该设置image.RenderTransformOrigin = new Point(0.5, 0.5)。最后,必须在 Canvas 上进行布局,即您必须调用其 MeasureArrange 方法。
  • 问题是我无法设置,因为我是插件
  • 然后创建一个新线程,在那里进行处理并将结果传递回您的插件线程。不要忘记在结果位图上调用Freeze() 以使其可以跨线程访问。
  • @Clemens 使用 RenderTransform 还是 LayoutTransform 更好? (区别在哪里?)
  • 你没有做任何布局,所以 RenderTransform 就足够了。阅读 MSDN 上的差异。

标签: c# wpf bitmapsource


【解决方案1】:

请注意,TransformedBitmap 仅支持正交变换,例如 90° 增量的旋转变换和缩放变换。不支持扭曲图像的变换。因此,对于旋转,您只能使用 90、180、270 度!正如原始问题中已经提到的那样!

【讨论】:

    【解决方案2】:

    只需使用 TransformedBitmap

    var rotatedImage = new TransformedBitmap(image, new RotateTransform(180));
    

    【讨论】:

    • 稍微相关:水平翻转可以使用new ScaleTransform(-1, 1, 0.5, 0.5)
    【解决方案3】:

    您可以在单独的线程中运行该代码。只需设置单线程单元 (STA)。

    Thread thread = new Thread(DoTheRotation);
    thread.SetApartmentState(ApartmentState.STA);
    thread.Start();
    thread.Join();
    

    线程调用的方法中的旋转代码:

    public void DoTheRotation()
    {
        var image = new Canvas();
        image.Width = myBitmapSource.PixelWidth;
        image.Height = myBitmapSource.PixelHeight;
        image.Background = new ImageBrush(myBitmapSource);
        image.RenderTransform = new RotateTransform(angle);
        RenderTargetBitmap rtb = new RenderTargetBitmap(myBitmapSource.PixelWidth, myBitmapSource.PixelHeight, myBitmapSource.DpiX, myBitmapSource.DpiY, myBitmapSource.Format);
        rtb.Render(image);
    }
    

    那么你只需要更改代码来传递对象。

    【讨论】:

    • 我还需要调用 .Freeze() !
    猜你喜欢
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    • 2016-08-20
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多