1 year ago
#58198
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