5

我正在尝试创建位图图像,并具有以下代码:

RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(uielement);

IBuffer pixels = await renderTargetBitmap.GetPixelsAsync();

. . .

var pixelArray = pixels.ToArray();

为了获得ToArray()延期,我遇到了这个问题。所以我补充说:

using System.Runtime.InteropServices.WindowsRuntime; // For ToArray

到我的代码。但是,当我运行时,我收到以下错误:

抛出异常:System.Runtime.WindowsRuntime.dll 中的“System.ArgumentException”

附加信息:指定的缓冲区索引不在缓冲区容量内。

当我深入研究细节时,它在堆栈跟踪中说:

在 >System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(IBuffer 源,UInt32 sourceIndex,Int32 计数)在 >System.Runtime.InteropServices.WindowsRuntime.WindowsRuntimeBufferExtensions.ToArray(IBuffer 源)

这种提取像素阵列的方法是否仍然适用于 UWP?如果是,有什么方法可以从此错误消息中获取更多详细信息?

4

2 回答 2

1

这种提取像素阵列的方法绝对适用于 UWP。至于错误,反编译后ToArray()是这样的:

public static byte[] ToArray(this IBuffer source)
{
  if (source == null)
    throw new ArgumentNullException("source");
  return WindowsRuntimeBufferExtensions.ToArray(source, 0U, checked ((int) source.Length));
}

换句话说,它调用ToArray带有起始索引和长度的重载:

public static byte[] ToArray(this IBuffer source, uint sourceIndex, int count)
{
  if (source == null)
    throw new ArgumentNullException("source");
  if (count < 0)
    throw new ArgumentOutOfRangeException("count");
  if (sourceIndex < 0U)
    throw new ArgumentOutOfRangeException("sourceIndex");
  if (source.Capacity <= sourceIndex)
    throw new ArgumentException(SR.GetString("Argument_BufferIndexExceedsCapacity"));
  if ((long) (source.Capacity - sourceIndex) < (long) count)
    throw new ArgumentException(SR.GetString("Argument_InsufficientSpaceInSourceBuffer"));
  byte[] destination = new byte[count];
  WindowsRuntimeBufferExtensions.CopyTo(source, sourceIndex, destination, 0, count);
  return destination;
}

几乎可以肯定会导致您的问题的行:

  if (source.Capacity <= sourceIndex)
    throw new ArgumentException(SR.GetString("Argument_BufferIndexExceedsCapacity"));

...因为sourceIndex必然是 0,这意味着它source.Capacity也是 0。

我建议您在代码中添加一些工具来检查IBuffer

RenderTargetBitmap rtb = new RenderTargetBitmap();
await rtb.RenderAsync(element);

IBuffer pixelBuffer = await rtb.GetPixelsAsync();
Debug.WriteLine($"Capacity = {pixelBuffer.Capacity}, Length={pixelBuffer.Length}");
byte[] pixels = pixelBuffer.ToArray();

我认为您的问题很可能在通话之前ToArray发生。我在自己的 UWP 应用程序中使用完全相同的序列,得到如下调试输出:

Capacity = 216720, Length=216720
于 2015-12-16T10:50:36.713 回答
0

我在 UWP 应用程序中尝试截屏时遇到了同样的问题。

RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(uielement);

uielement什么时候给了我这个例外Window.Current.Content

但是当我尝试

RenderTargetBitmap renderTargetBitmap = new RenderTargetBitmap();
await renderTargetBitmap.RenderAsync(null);

相同的代码毫无例外地工作,并为我提供了 UWP 应用程序窗口的屏幕截图。

于 2018-12-25T10:01:30.970 回答