0

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
}

干杯。

4

1 回答 1

0

这个问题是 ImageSource 的设置方式......创建一个非重载的 Source 属性是问题......重命名这个然后将该属性设置为继承的源解决了这个问题。

干杯。

于 2012-07-24T14:18:29.283 回答