【问题标题】:Why SharpDX render my bitmap in grey and corrupted?为什么 SharpDX 将我的位图呈现为灰色和损坏?
【发布时间】:2017-01-04 10:34:36
【问题描述】:

我是 SharpDX 的新手,我想模拟代码以直接从内存渲染 24 位位图图像并显示到 PictureBox。 *此代码将在以后的项目中使用,以快速从内存中渲染图像。

使用标准 DrawImage() 方法渲染没有问题。我选择 SharpDX 因为 DrawImage 太慢了。

但是当我尝试使用 SharpDX 进行渲染时,图像会变成灰色并损坏(见下图)

我要渲染的图像是 24 位 RGB 位图。

使用 DrawImage

使用 SharpDX

我的代码有什么问题?

下面是我的代码:

using System;
using System.Windows.Forms;
using SharpDX;
using SharpDX.Direct2D1;
using System.Diagnostics;

namespace bitmap_test
{
    public partial class Form1 : Form
    {
        private System.Drawing.Bitmap image1 = null;
        private System.Drawing.Imaging.BitmapData bmpdata1 = null;

        //target of rendering
        WindowRenderTarget target;

        //factory for creating 2D elements
        SharpDX.Direct2D1.Factory factory = new SharpDX.Direct2D1.Factory();
        //this one is for creating DirectWrite Elements
        SharpDX.DirectWrite.Factory factoryWrite = new SharpDX.DirectWrite.Factory();

        private SharpDX.DXGI.Format bmp_format = SharpDX.DXGI.Format.B8G8R8A8_UNorm;
        private AlphaMode bmp_alphamode = AlphaMode.Ignore;

        public Form1()
        {
            InitializeComponent();
        }

        private void Form1_Load(object sender, EventArgs e)
        {
            InitSharpDX();

            //load 24-bit depth bitmap
            LoadBitmapFromFile(@"D:\lena.bmp"); //https://software.intel.com/sites/default/files/forum/351974/lena.bmp
        }

        private void InitSharpDX()
        {
            //Init Direct Draw
            //Set Rendering properties
            RenderTargetProperties renderProp = new RenderTargetProperties()
            {
                DpiX = 0,
                DpiY = 0,
                MinLevel = FeatureLevel.Level_10,
                PixelFormat = new PixelFormat(bmp_format, bmp_alphamode),
                Type = RenderTargetType.Hardware,
                Usage = RenderTargetUsage.None
            };

            //set hwnd target properties (permit to attach Direct2D to window)
            HwndRenderTargetProperties winProp = new HwndRenderTargetProperties()
            {
                Hwnd = this.pictureBox1.Handle,
                PixelSize = new Size2(this.pictureBox1.ClientSize.Width, this.pictureBox1.ClientSize.Height),
                PresentOptions = PresentOptions.Immediately
            };

            //target creation
            target = new WindowRenderTarget(factory, renderProp, winProp);
        }

        //load bmp file into program memory
        private void LoadBitmapFromFile(string file)
        {
            image1 = (System.Drawing.Bitmap)System.Drawing.Image.FromFile(file, true);
            var sourceArea = new System.Drawing.Rectangle(0, 0, image1.Width, image1.Height);
            bmpdata1 = image1.LockBits(sourceArea, System.Drawing.Imaging.ImageLockMode.ReadOnly, System.Drawing.Imaging.PixelFormat.Format24bppRgb);
            image1.UnlockBits(bmpdata1);
        }

        private void drawBitmap(IntPtr pBuffer, int len, int width, int height)
        {
            try
            {
                var bitmapProperties = new BitmapProperties(new PixelFormat(bmp_format, bmp_alphamode));

                var size = new Size2(width, height);

                int stride = width * 3; //only want RGB, ignore alpha

                var bmp = new SharpDX.Direct2D1.Bitmap(target, size, new DataPointer(pBuffer, len), stride, bitmapProperties);

                //draw elements
                Draw(ref bmp);
                bmp.Dispose();
            }
            finally
            {
            }
        }

        private void Draw(ref SharpDX.Direct2D1.Bitmap bmp)
        {
            //begin rendering
            target.BeginDraw();

            //clear target
            target.Clear(null);

            //draw bitmap
            target.DrawBitmap(bmp, 1.0f, BitmapInterpolationMode.Linear);

            //end drawing
            target.EndDraw();
        }

        //draw image using SharpDX
        private void cmdRender_Click(object sender, EventArgs e)
        {
            if (bmpdata1 != null)
            {
                int len = bmpdata1.Width * bmpdata1.Height * 3;
                var sw = Stopwatch.StartNew();
                drawBitmap(bmpdata1.Scan0, len, bmpdata1.Width, bmpdata1.Height);
                sw.Stop();
                Console.WriteLine("SharpDX: {0}us", sw.ElapsedTicks / (TimeSpan.TicksPerMillisecond / 1000));
            }
        }

        //draw image using DrawImage()
        private void cmdDrawImage_Click(object sender, EventArgs e)
        {
            if (image1 != null)
            {
                var g = pictureBox1.CreateGraphics();
                var sourceArea = new System.Drawing.Rectangle(0, 0, image1.Width, image1.Height);
                var sw = Stopwatch.StartNew();
                g.DrawImage(image1, sourceArea); //DrawImage is slow
                sw.Stop();
                Console.WriteLine("DrawImage: {0}us", sw.ElapsedTicks/(TimeSpan.TicksPerMillisecond / 1000));
            }
        }
    }
}

【问题讨论】:

    标签: c# image bitmap directx sharpdx


    【解决方案1】:

    bmp_format B8G8R8A8_UNorm 与 System.Drawing 锁定格式不匹配 Format24bppRgb... 也使用 bmpdata1.Stride 而不是计算潜在的无效步幅。

    【讨论】:

    • 知道我应该为 Format24bppRgb 使用什么格式吗?
    【解决方案2】:

    您的步幅通常是位图宽度乘以字节深度。

    所以 512 * 4 将是一个 512 宽的位图,带有 32 位调色板。比如RGBA

    【讨论】:

      猜你喜欢
      • 1970-01-01
      • 1970-01-01
      • 2017-10-16
      • 1970-01-01
      • 1970-01-01
      • 2019-11-07
      • 2014-10-28
      • 1970-01-01
      • 1970-01-01
      相关资源
      最近更新 更多