1 year ago

#58198

test-img

iegrm

Converting GDI System.Drawing.Bitmap to SharpDX Bitmap

I have the following code for converting a GDI Bitmap to a SharpDX Bitmap and renderering that to a form handle.

public Renderer(IntPtr hWnd, Size size) {
    RenderHandle = hWnd;
    RenderSize = size;
    DeviceManager = new DXGIDeviceManager();

    using(var dxgiFactory1 = new SharpDX.DXGI.Factory1()) {
        using(var adapter1 = dxgiFactory1.Adapters1.FirstOrDefault(x => !x.Description1.Flags.HasFlag(AdapterFlags.Software))) {
            if(adapter1 == null) { return; }

            OutputDevice = new SharpDX.Direct3D11.Device(adapter1, DeviceCreationFlags.BgraSupport | DeviceCreationFlags.VideoSupport);
            DeviceManager.ResetDevice(OutputDevice);
            using(var deviceMultithread = OutputDevice.QueryInterface<DeviceMultithread>()) {
                deviceMultithread.SetMultithreadProtected(new RawBool(true));
            }
        }
    }

    using(var direct2d1Factory1 = new SharpDX.Direct2D1.Factory1()) {
        using(var dxFac = new SharpDX.DXGI.Factory2(false)) {
            using(var dxDev = OutputDevice.QueryInterface<SharpDX.DXGI.Device>()) {
                Output2D1Device = new SharpDX.Direct2D1.Device(direct2d1Factory1, dxDev);

                using(var dxDev1 = OutputDevice.QueryInterface<SharpDX.DXGI.Device1>()) {
                    var swapChainDescription = new SwapChainDescription1 {
                        SampleDescription = new SampleDescription(1, 0),
                        SwapEffect = SwapEffect.FlipSequential,
                        Scaling = Scaling.Stretch, //None
                        Usage = Usage.RenderTargetOutput,
                        Format = Format.B8G8R8A8_UNorm,
                        BufferCount = 2,
                        Width = RenderSize.Width,
                        Height = RenderSize.Height
                    };
                    SwapChain = new SwapChain1(dxFac, dxDev1, RenderHandle, ref swapChainDescription);
                    dxDev1.MaximumFrameLatency = 1;
                }
            }
        }
    }
}

public void Update(System.Drawing.Bitmap gdibmp) {
    using(var renderTexture = Texture2D.FromSwapChain<Texture2D>(SwapChain, 0)) {
        using(var renderSurface = renderTexture.QueryInterface<Surface>()) {
            using(var dc = new SharpDX.Direct2D1.DeviceContext(Output2D1Device, DeviceContextOptions.EnableMultithreadedOptimizations)) {
                using(var bmp = new Bitmap1(dc, renderSurface)) {
                    dc.Target = bmp;
                    dc.BeginDraw();

                    SharpDX.Direct2D1.Bitmap dxbmp = GDIBitmapToDXBitmap(dc, gdibmp);
                    dc.DrawBitmap(dxbmp, 1f, BitmapInterpolationMode.Linear);

                    dc.Flush();
                    dc.EndDraw();
                }
            }
        }
    }
}

private SharpDX.Direct2D1.Bitmap GDIBitmapToDXBitmap(SharpDX.Direct2D1.DeviceContext dc, System.Drawing.Bitmap bmp) {
    BitmapProperties props = new BitmapProperties(new PixelFormat(Format.B8G8R8A8_UNorm, SharpDX.Direct2D1.AlphaMode.Premultiplied));
    int stride = bmp.Width * 4;

    using(SharpDX.DataStream dataStream = new SharpDX.DataStream(bmp.Height * stride, false, true)) {
        for(int y = 0; y < bmp.Height; y++) {
            for(int x = 0; x < bmp.Width; x++) {
                System.Drawing.Color c = bmp.GetPixel(x, y);
                int a = c.A;
                int r = (c.R * a) / 255;
                int g = (c.G * a) / 255;
                int b = (c.B * a) / 255;
                int bgra = b | (g << 8) | (r << 16) | (a << 24);
                dataStream.Write(bgra);
            }
        }

        return new SharpDX.Direct2D1.Bitmap(dc, new Size2(bmp.Width, bmp.Height), dataStream, stride, props);
    }
}

I have used similar code in the past for drawing lines/text and such to windows form controls, but I am not entirely sure whether I'm doing it correctly to draw bitmaps.

I get the following error on the return from GDIBitmapToDXBitmap:

Attempted to read or write protected memory. This is often an indication that other memory is corrupt

What am I doing wrong here?

c#

bitmap

directx

gdi

sharpdx

0 Answers

Your Answer

Accepted video resources