【问题标题】:copy raw pixel data in c#在c#中复制原始像素数据
【发布时间】:2011-10-14 18:43:43
【问题描述】:

我正在尝试将位图的像素复制到 DirectX 纹理中。从两者中获取 IntPtr 很简单,但是如何有效地复制像素数据?

   var data = FBitmap.LockBits(..)
   var rect = texture.LockRectangle(0, LockFlags.None);

   IntPtr from = data.Scan0;
   IntPtr to = rect.Data.DataPointer;

   //copy data  

   texture.UnlockRectangle(0);
   FBitmap.UnlockBits(data);

我尝试使用 Marshal.Copy,但它需要将像素作为数组,我当然想避免另一个副本。

【问题讨论】:

  • 如果你只是想将图像字节分配给纹理的地址空间,你需要一个位图吗?你能从任何地方读取图像作为二进制数据然后复制吗?
  • 我需要复制数据,因为有一个 SVG 渲染器将其像素渲染到位图中。然后在 3d 环境中绘制纹理。

标签: c# copy unmanaged


【解决方案1】:

您可以使用 Windows API CopyMemory - 别名“RtlMoveMemory”。比所有那些 LockBits 的东西都要快得多......

http://www.pinvoke.net/default.aspx/urlmon/CopyMemory.html

【讨论】:

【解决方案2】:

如果您谈论的是每个 CPU 周期都很重要的那种前沿效率,那么您最好直接将数据指针与 unsafe 代码一起使用。

没有真正快速的方法可以将平面数组映射到像 Array 这样的实际托管对象上,您必须逐字节复制像素数据。

【讨论】:

  • +1 - 最快的是不安全的代码。我已经对此进行了多次测试,尤其是如果您想避免复制。
  • 你的意思是对所有像素的非托管 for 循环比内存移动更快?
  • 不复制是最好的复制优化,是的。
  • 当然.. 但我需要一个副本,因此 SVG 渲染器可以在显示纹理时将新像素绘制到位图中。
  • 我不知道你在做什么或为什么,所以这取决于你。但是,我确实质疑您使用托管对象作为临时纹理数据临时持有者的奇怪思维方式,这些临时纹理数据您只想推送到显卡。
猜你喜欢
  • 2012-10-06
  • 2014-03-29
  • 1970-01-01
  • 2017-03-22
  • 1970-01-01
  • 2012-05-11
  • 1970-01-01
  • 1970-01-01
  • 1970-01-01
相关资源
最近更新 更多