2013-07-24 23 views
0
Image<Bgr, Byte> video = cap.QueryFrame(); 
Texture2D t = new Texture2D(GraphicsDevice, video.Width, video.Height, false, SurfaceFormat.Color); 
t.SetData<byte>(video.Bytes); 

ArgumentException的是未處理如何將emgu圖片轉換爲XNA Texture2D?

傳遞的數據的尺寸過大或過小這一資源。

回答

1

我perfered方式是「拯救」的圖像到內存中,然後與Texture2D.FromStream功能加載它。

Texture2D t; 

using(MemoryStream memStream = new MemoryStream()) 
{ 
    Image<Bgr, Byte> video = cap.QueryFrame(); 
    cap.save(memStream, ImageFormat.PNG); 
    t = Texture2D.FromStream(GraphicsDevice, memStream, video.Width, video.Height, 1f) 
} 

這將與NonPremultiplied BlendStates工作,但如果你想使用預乘阿爾法你應該運行的Texture2D雖然下面的函數。這個功能只是簡單地使用GPU來快速預處理紋理的alpha,就像內容處理器一樣。

static public void PreMultiplyAlpha(this Texture2D texture) {    

     //Setup a render target to hold our final texture which will have premulitplied color values 
     var result = new RenderTarget2D(texture.GraphicsDevice, texture.Width, texture.Height); 

     texture.GraphicsDevice.SetRenderTarget(result); 
     texture.GraphicsDevice.Clear(Color.Black); 

     // Using default blending function 
     // (source × Blend.SourceAlpha) + (destination × Blend.InvSourceAlpha) 
     // Destination is zero so the reduces to 
     // (source × Blend.SourceAlpha) 
     // So this multiplies our color values by the alpha value and draws it to the RenderTarget 
     var blendColor = new BlendState { 
      ColorWriteChannels = ColorWriteChannels.Red | ColorWriteChannels.Green | ColorWriteChannels.Blue, 
      AlphaDestinationBlend = Blend.Zero, 
      ColorDestinationBlend = Blend.Zero, 
      AlphaSourceBlend = Blend.SourceAlpha, 
      ColorSourceBlend = Blend.SourceAlpha 
     }; 

     var spriteBatch = new SpriteBatch(texture.GraphicsDevice); 
     spriteBatch.Begin(SpriteSortMode.Immediate, blendColor); 
     spriteBatch.Draw(texture, texture.Bounds, Color.White); 
     spriteBatch.End(); 

     // Simply copy over the alpha channel 
     var blendAlpha = new BlendState { 
      ColorWriteChannels = ColorWriteChannels.Alpha, 
      AlphaDestinationBlend = Blend.Zero, 
      ColorDestinationBlend = Blend.Zero, 
      AlphaSourceBlend = Blend.One, 
      ColorSourceBlend = Blend.One 
     }; 

     spriteBatch.Begin(SpriteSortMode.Immediate, blendAlpha); 
     spriteBatch.Draw(texture, texture.Bounds, Color.White); 
     spriteBatch.End(); 

     texture.GraphicsDevice.SetRenderTarget(null); 

     var t = new Color[result.Width * result.Height]; 
     result.GetData(t); 
     texture.SetData(t); 
    } 
+0

這種方法有什麼優點嗎?更好的內存使用?速度? – sav

+1

那麼如果你想使用PreMultiplied Alpha(默認情況下是XNA),那麼GPU技巧是必要的。 PreMultiplied Alpha與非PreMultiplied Alpha相比性能略有提升。保存的優點是您不必擔心圖像在內部如何顯示。圖像可以是絕對的任何格式,因爲你保存和加載爲PNG,所以它會提取一些複雜性。除非這是實時的,否則性能問題不值得考慮。相同的內存使用情況,因爲您必須克隆字節數組,因爲顏色格式不正確。 – ClassicThunder

+0

我想也值得注意的是,png壓縮是無損的,所以不用擔心信息丟失。 – sav

0

視頻以(藍色,綠色,紅色)格式存儲圖像。而texture2d也需要額外的alpha像素。

Image<Bgr, Byte> video = cap.QueryFrame(); 
Image<Bgra, Byte> video2 = video.Convert<Bgra, Byte>(); 
Texture2D t = new Texture2D(GraphicsDevice, video.Width, video.Height, false, SurfaceFormat.Color); 
t.SetData<byte>(video2.Bytes);