f 我有一个 ContentControl... 并且其 Content 设置为自定义 Image... 并且自定义 Image 具有名为 Source 的字段,该字段包含位图数据...我需要哪些额外步骤来确保 ContentControl 显示该位图数据? 我在想我做错了这一步......因为 Source 只是一个字段?
此外,位图数据不断变化。
public class VideoRenderer : System.Windows.Controls.Image
{
#region Fields
protected DateTime lastFrameTimestamp;
protected Rectangle rect;
protected System.Timers.Timer timer;
protected BitmapData bitmapData;
protected Bitmap bitmap = null;
private Video videoObject = null;
private Participant participantObject = null;
private bool isRunning = false;
private int updateInterval = 50;
private uint key = 0;
private int videoWidth = 0;
private int videoHeight = 0;
private SkypeRoot skypeRef;
private FrameTransport frameTransport;
private double fps = 0;
private System.Windows.Media.ImageSource source;
object bitmapLock = new object();
#endregion
/// <summary>
/// Gets and sets the source of the video renderer image.
/// </summary>
public new System.Windows.Media.ImageSource Source
{
get { return source; }
set { source = value; }
}
#region Constructors
/// <summary>
/// Constructor.
/// </summary>
/// <param name="skype"></param>
public VideoRenderer(SkypeRoot skype)
{
this.skypeRef = skype;
}
#endregion
#region Internal Members
/// <summary>
/// Convert frame to a bitmap.
/// </summary>
/// <returns></returns>
internal bool MoveFrameToBitmap()
{
lock (bitmapLock)
{
if (frameTransport.bitmapDataSize == 0)
{
return false;
}
bool ResolutionHasChanged = ((videoWidth != frameTransport.width) | (videoHeight != frameTransport.height));
if ((bitmap == null) | ResolutionHasChanged)
{
if (bitmap != null)
{
bitmap.Dispose();
}
videoHeight = frameTransport.height;
videoWidth = frameTransport.width;
bitmapData = null;
bitmap = new Bitmap(videoWidth, videoHeight);
bitmapData = new BitmapData();
bitmapData.Width = videoWidth;
bitmapData.Height = videoHeight;
bitmapData.PixelFormat = System.Drawing.Imaging.PixelFormat.Format24bppRgb;
rect = new Rectangle(0, 0, videoWidth, videoHeight);
}
bitmap.LockBits(rect, ImageLockMode.ReadWrite, System.Drawing.Imaging.PixelFormat.Format24bppRgb, bitmapData);
IntPtr ptr = bitmapData.Scan0;
Marshal.Copy(frameTransport.bitmapData, 0, ptr, frameTransport.bitmapDataSize);
bitmap.UnlockBits(bitmapData);
if (ResolutionHasChanged) skypeRef.events.FireOnVideoResolutionChanged(this, new RootEvents.OnVideoResolutionChangedArgs(videoWidth, videoHeight));
return true;
}
}
/// <summary>
/// Draw the bitmap to the picturebox.
/// </summary>
internal void DrawBitmap()
{
lock (bitmapLock)
{
using (MemoryStream memory = new MemoryStream())
{
bitmap.Save(memory, ImageFormat.Png);
memory.Position = 0;
BitmapImage bitmapImage = new BitmapImage();
bitmapImage.BeginInit();
bitmapImage.StreamSource = memory;
bitmapImage.CacheOption = BitmapCacheOption.OnLoad;
bitmapImage.EndInit();
source = bitmapImage;
}
}
}
#endregion
#region External Members
/// <summary>
/// Start the video rendering.
/// </summary>
public void Start()
{
if (isRunning)
{
return;
}
if (videoObject == null)
{
throw new Exception("Error: cannot start rendering when the associated video object is null.");
}
isRunning = true;
frameTransport = new FrameTransport();
timer = new System.Timers.Timer();
timer.Interval = updateInterval;
timer.Enabled = false;
timer.Elapsed += TimerTick;
Int32[] preferences = new Int32[1];
preferences[0] = MakeFourCC('B', 'I', '2', '4');
frameTransport.SetPreferences(1, preferences);
key = frameTransport.Key();
videoObject.SetRemoteRendererID(key);
lastFrameTimestamp = DateTime.Now;
timer.Start();
}
#endregion
#region Events
/// <summary>
/// Handle the timer when video is running.
/// </summary>
/// <param name="sender"></param>
/// <param name="e"></param>
private void TimerTick(object sender, EventArgs e)
{
if (frameTransport.IsNewFrameAvailable())
{
bool frameOk = frameTransport.GetFrame();
if (frameOk)
{
bool bitmapOk = MoveFrameToBitmap();
if (bitmapOk)
{
AddCustomGraphics();
DrawBitmap();
double msSinceLastFrame = (Int32)DateTime.Now.Subtract(lastFrameTimestamp).TotalMilliseconds;
fps = 1000 / msSinceLastFrame;
lastFrameTimestamp = DateTime.Now;
}
}
}
}
#endregion
}
干杯。