[英]Marshal.Copy() is not copying to bitmap
我正在处理一个图像处理项目,我读到操作位图图像的最快方法是使用 Marshal.Copy() 从字节数组中复制它。 但是,无论出于何种原因,都没有将任何内容从我的字节数组复制到我的位图,并且没有明确的原因。 这是我用来复制到我的位图的代码:
public void UpdateImage()
{
var data = image.LockBits(
new Rectangle(Point.Empty, image.Size),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb);
Marshal.Copy(backBuffer, 0, data.Scan0, backBuffer.Length);
image.UnlockBits(data);
Console.WriteLine("UpdateImage");//For debugging purposes
}
我试图用全黑填充图像,并查看 backBuffer 的数据,它似乎是正确的,并且正如预期的那样,当我检查“图像”的任何像素时,它完全是空白的。 我不知道为什么什么也没有发生。 任何建议将不胜感激!
编辑:我很抱歉,我在这里有点新,让我提供更多信息。 具体来说,我正在使用 Cloo/OpenCL 进行一些 GPU 加速的图像处理。 我想用黑色填充屏幕以确保我做的事情正确,尽管我显然不是。 这是我正在使用的整个类文件:
public class RenderTarget
{
public GraphicsDevice GraphicsDevice;
private byte[] backBuffer;
public Bitmap image;
private ComputeKernel fillKernel;
private ComputeProgram fillProgram;
public void UpdateImage()
{
var data = image.LockBits(
new Rectangle(Point.Empty, image.Size),
ImageLockMode.WriteOnly,
PixelFormat.Format32bppArgb);
Marshal.Copy(backBuffer, 0, data.Scan0, backBuffer.Length);
image.UnlockBits(data);
Console.WriteLine("UpdateImage");
}
//Test method ONLY
public void FillScreen(Color color)
{
if (fillProgram == null)//temporary, all kernels should be compiled on start up. In fact, these probably should be static
{
string fillText = @"
kernel void fillScreen(global uchar* data_out, int from, int to, uchar a, uchar r, uchar g, uchar b){
for (int i = from; i < to; i += 4){
data_out[i] = a;
data_out[i + 1] = r;
data_out[i + 2] = g;
data_out[i + 3] = b;
}
}";
fillProgram = new ComputeProgram(GraphicsDevice.context, fillText);
fillProgram.Build(null, null, null, IntPtr.Zero);
fillKernel = fillProgram.CreateKernel("fillScreen");
}
ComputeBuffer<byte> backBufferBuffer = new ComputeBuffer<byte>(GraphicsDevice.context, ComputeMemoryFlags.ReadOnly | ComputeMemoryFlags.UseHostPointer, backBuffer);
fillKernel.SetMemoryArgument(0, backBufferBuffer);
for (int i = 0; i < backBuffer.Length / 10000; i++)
{
fillKernel.SetValueArgument<int>(1, i * 10000);
fillKernel.SetValueArgument<int>(2, (i + 1) * 10000);
fillKernel.SetValueArgument<byte>(3, color.A);
fillKernel.SetValueArgument<byte>(4, color.R);
fillKernel.SetValueArgument<byte>(5, color.G);
fillKernel.SetValueArgument<byte>(6, color.B);
GraphicsDevice.queue.ExecuteTask(fillKernel, null);
}
GraphicsDevice.queue.ReadFromBuffer(backBufferBuffer, ref backBuffer, false, null);
GraphicsDevice.queue.Finish();
}
public RenderTarget(int Width, int Height, GraphicsDevice device)
{
image = new Bitmap(Width, Height);
backBuffer = new byte[4 * Width * Height];
GraphicsDevice = device;
//Fill the screen with black
FillScreen(Color.Black);
UpdateImage();
Console.WriteLine(image.GetPixel(0, 0).A);
}
}
我已经检查以确保 backBuffer 是正确的。 (对于 backBuffer 的前四个元素,我预期的值是 255, 0, 0, 0)。
好的,我知道出了什么问题。 我在 backBuffer 中的格式错误。 当它应该被订购为 RGBA 时,我期望它是 ARGB。 所以,我在“fillText”中的代码有问题。
声明:本站的技术帖子网页,遵循CC BY-SA 4.0协议,如果您需要转载,请注明本站网址或者原文地址。任何问题请咨询:yoyou2525@163.com.