Marshal.Copy()没有复制到位图

时间:2017-10-23 04:58:26

标签: c# image-processing marshalling

我正在开发一个图像处理项目,我已经读过,操作位图图像的最快方法是使用Marshal.Copy()从字节数组中复制它。但是,无论出于何种原因,没有任何东西从我的字节数组复制到我的Bitmap,并且没有明确的原因。这是我用来复制到我的Bitmap的代码:

    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)。

1 个答案:

答案 0 :(得分:0)

好的,我弄清楚出了什么问题。我在backBuffer中的格式错了。应该订购RGBA时,我期待它是ARGB。所以,我的代码在'fillText'中存在问题。