0

我正在 C#/UWP/Win2D 应用程序中基于非标准像素格式的文件快速制作图像动画。图像之间存在相关性(想想翻书动画),但没有任何程序化。

我已经编写了一个原型,并在下面包含了相关代码。“白色”和“黑色”颜色最终将转换为颜色查找表(例如 5 = 白色)

....
//Create render target in function elsewhere
CanvasRenderTarget crt = new CanvasRenderTarget(Sender, FrameWidth, FrameHeight, defaultDpi);
GenerateNextFrame(crt);
....

private void GenerateNextFrame(CanvasRenderTarget frame)
{
    var frameSize = FrameHeight * FrameWidth * sizeof(ushort);
    var frameBytes = new byte[frameSize];
    var frameShorts = new ushort[FrameWidth * FrameHeight];
    var colors = new Color[FrameWidth * FrameHeight];
    var white = Colors.White;
    var black = Colors.Black;
    var comp = (ushort.MaxValue / 2);

    //read bytes from file
    FrameFileStream.AsStreamForRead().Read(frameBytes, 0, frameSize);
    //convert bytes to shorts
    System.Buffer.BlockCopy(frameBytes, 0, frameShorts, 0, frameSize);

    //convert shorts to colors
    for (var i = 0; i < colors.Length; i++)
    {
        colors[i] = (frameShorts[i] < comp) ? white : black;
    }
    //set colors on frame
    frame.SetPixelColors(colors);
}

性能很好~60FPS,FrameWidth/FrameHeight 为 512,但在 1024 时下降到~30FPS。任何比这更大的性能更差。

使用大数据对此进行分析表明,颜色数组的循环和 SetPixelColors 调用是瓶颈。

我尝试了几种方法来加快速度(PLINQ、Parallel.ForEach、数据预排队),但未能比上面找到的形式更快。

我相信处理这个问题的正确方法是为 CanvasRenderTarget 创建一种新的受支持类型的 DirectXPixelFormat,这样我就可以使用 SetPixelBytes。这似乎是不可能的。

下一个正确的选项似乎是编写一个接受 frameBytes 的 PixelShaderEffect,以灰度创建像素,然后将其用作另一个效果的来源来设置颜色。

我找不到任何创建 IGraphicsEffectSource 的示例。

任何建议、文档,或者最重要的是,一个有效的“这是您将字节数组传递到 PixelShaderEffect 的方式”将不胜感激。

4

0 回答 0