簡體   English   中英

Marshal.Copy() 沒有復制到位圖

[英]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.

 
粵ICP備18138465號  © 2020-2024 STACKOOM.COM