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?
傳遞的數據的尺寸過大或過小這一資源。
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?
傳遞的數據的尺寸過大或過小這一資源。
我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);
}
視頻以(藍色,綠色,紅色)格式存儲圖像。而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);
這種方法有什麼優點嗎?更好的內存使用?速度? – sav
那麼如果你想使用PreMultiplied Alpha(默認情況下是XNA),那麼GPU技巧是必要的。 PreMultiplied Alpha與非PreMultiplied Alpha相比性能略有提升。保存的優點是您不必擔心圖像在內部如何顯示。圖像可以是絕對的任何格式,因爲你保存和加載爲PNG,所以它會提取一些複雜性。除非這是實時的,否則性能問題不值得考慮。相同的內存使用情況,因爲您必須克隆字節數組,因爲顏色格式不正確。 – ClassicThunder
我想也值得注意的是,png壓縮是無損的,所以不用擔心信息丟失。 – sav