2017-01-04 63 views
0

我是SharpDX的新手,我想模擬代碼來直接從內存中渲染24位位圖圖像並顯示到PictureBox。 *此代碼將在以後的項目中使用,以快速從內存中渲染圖像。爲什麼SharpDX渲染我的位圖灰色和損壞?

我沒有問題使用標準DrawImage()方法渲染。我選擇SharpDX,因爲DrawImage太慢了。

但是當我嘗試使用SharpDX渲染,圖像變成灰色的顏色和損壞的(見下圖)

我要呈現的圖像是24位RGB位圖。

使用的DrawImage enter image description here

使用SharpDX enter image description here

什麼是錯我的代碼?

下面是我的代碼:

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)); 
      } 
     } 
    } 
} 

回答

0

bmp_formatB8G8R8A8_UNorm不匹配System.Drawing中鎖定格式Format24bppRgb ......還用bmpdata1.Stride,而不是計算潛在無效的步伐。

+0

任何想法我應該使用Format24bppRgb格式? – Dennis

0

你的步幅通常是由字節深度倍增的位圖寬度。

所以512 * 4將是一個512位寬的32位調色板位圖。例如RGBA