【问题标题】:Why is rotation much faster on Image than using BitmapEncoder?为什么 Image 上的旋转比使用 BitmapEncoder 快得多?
【发布时间】:2016-09-05 11:21:14
【问题描述】:

使用

旋转图像
image.RenderTransform = new RotateTransform()...

几乎是立即的。 另一方面,使用

bitmapEncoder.BitmapTransform.Rotation = BitmapRotation.Clockwise90Degrees...

很多慢(在FlushAsync()) - 超过半秒。

这是为什么呢?有没有办法利用快速旋转来旋转位图?

【问题讨论】:

    标签: c# xaml win-universal-app uwp uwp-xaml


    【解决方案1】:

    第一个image.RenderTransform 将使用硬件渲染来渲染位图。 (GPU) 图像不旋转,但会旋转/缩放显示。 (将仅直接从/在显存中访问可见像素)

    第二个将由 CPU 旋转图像本身(所有像素)。它将为结果创建新的内存。 (非显存)


    更新:

    有没有办法使用 GPU 来编辑位图? 取决于你需要什么:

    如果您想使用 GPU。您可以使用托管包装器(如 Slim DX/Sharp DX)这将需要很长时间才能获得结果。不要忘记,通过 gpu 重新光栅化图像可能会导致质量下降。

    如果您只想旋转图像(0、90、180、270)?您可以使用带有 de ScanLine0 选项的 Bitmap 类。 (这是为了保持质量和大小),您可以创建一个快速的实现。

    看这里: Fast work with Bitmaps in C#

    我会为每个角度 (0,90,180,270) 创建一个算法。因为您不想计算每个像素的 x、y 位置。像下面这样..


    提示:

    尝试丢失乘法/除法。

    /*This time we convert the IntPtr to a ptr*/
    byte* scan0 = (byte*)bData.Scan0.ToPointer();
    
    for (int i = 0; i < bData.Height; ++i)
    {
        for (int j = 0; j < bData.Width; ++j)
        {
            byte* data = scan0 + i * bData.Stride + j * bitsPerPixel / 8;
    
            //data is a pointer to the first byte of the 3-byte color data
        }
    }
    

    变成这样:

    /*This time we convert the IntPtr to a ptr*/
    byte* scan0 = (byte*)bData.Scan0.ToPointer();
    
    byte* data = scan0;
    
    int bytesPerPixel = bitsPerPixel / 8;
    
    for (int i = 0; i < bData.Height; ++i)
    {
        byte* data2 = data;
        for (int j = 0; j < bData.Width; ++j)
        {
            //data2 is a pointer to the first byte of the 3-byte color data
    
            data2 += bytesPerPixel;
        }
        data += bData.Stride;
    }
    

    【讨论】:

    • 谢谢。 +1。如果您有一些文档,那就太好了。更重要的是:有没有办法使用 GPU 来编辑位图?
    • 那些微优化不会做太多,如果有的话。不要低估编译器的优化器。始终查看编译器的输出。并在应用任何更改时始终进行配置。
    • 根据我的经验,执行时间之间存在很大差异。我同意,你永远不应该预先优化代码,因为它的可读性可能会降低并且需要更多的开发时间。
    • 谢谢。不幸的是,UWP 不允许我们使用位图,只能使用类似的对象。但我明白了。
    猜你喜欢
    • 1970-01-01
    • 2023-03-31
    • 1970-01-01
    • 1970-01-01
    • 2014-04-21
    • 2015-02-09
    • 1970-01-01
    • 1970-01-01
    • 1970-01-01
    相关资源
    最近更新 更多