首页 > 解决方案 > 图片框移植到 WPF

问题描述

我在将我picturebox的 from移植Windows FormWPF.

我的问题不在于它picturebox本身,而是我在显示imageget from NetworkStreamfrom a Threadinto an Imagein时遇到了麻烦WPF

NetworkStreamTcpClient连接客户端服务器得到这个。

这是我的 Windows 窗体代码(相关部分):

Thread getImage;

void StartReceiving(){
    getImage = new Thread(ReceiveImage);
    getImage.Start();
}


private void ReceiveImage()
{
    BinaryFormatter binaryFormatter = new BinaryFormatter();
    while (client.Connected)
    {
        mainStream = client.GetStream();
        try
        {
            pictureBox1.Image = (Image)binaryFormatter.Deserialize(mainStream);
        }
        catch (Exception ex) { }
    }
}

此代码有效,我每 100 毫秒循环获取一次图像,我需要更新该源。

WPF我尝试使用Image并设置它的源(我尝试了 UriSource 和 StreamSource)但没有成功。我得到了thread exceptions,“ nothing appens”错误,...

这是我的最后一个代码,它会导致Thread错误,但我不知道还有什么可以尝试使其符合线程。(我只贴了相关部分)

private readonly Thread getImage;

public SecondWindow(int port)
{
    InitializeComponent();
    client = new TcpClient();
    getImage = new Thread(new ThreadStart(ReceiveImage));
    while (!client.Connected)
    {
        server.Start();
        client = server.AcceptTcpClient();
    }
    getImage.Start();
}

private void ReceiveImage()
{
    BinaryFormatter binaryFormatter = new BinaryFormatter();
    BitmapImage imgSrc = new BitmapImage();
    while (client.Connected)
    {

        var mainStream = client.GetStream();
        int loop = 0;
        while (!mainStream.DataAvailable && loop < 500)
        {
            loop++;
            Thread.Sleep(10);
        }
        if (mainStream.DataAvailable)
        {
            try
            {
                imgSrc = new BitmapImage();
                imgSrc.BeginInit();
                imgSrc.StreamSource = mainStream;
                imgSrc.CacheOption = BitmapCacheOption.OnLoad;
                imgSrc.EndInit();
                if (imgSrc.CanFreeze && !imgSrc.IsFrozen)
                    imgSrc.Freeze();
            }
            catch (Exception ex)
            {
                Console.WriteLine(ex);
            }

            if (displayImage.Dispatcher.CheckAccess())
            {
                displayImage.Source = imgSrc;
            }
            else
            {
                Action act = () => { displayImage.Source = imgSrc; };
                displayImage.Dispatcher.BeginInvoke(act);
            }
        }
    }
}

在上面的代码中,我有两个问题:第一个imgSrc永远不会冻结

第二个(可能是第一个问题的直接后果),我得到InvalidOperationException The calling thread cannot access this object because a different thread owns it

感谢大家的支持


我解决了!!解决方案是使用其他一些方法来反序列化整个流,然后将其应用于图像源!

这可能不是最好的解决方案,但这个答案让我结束了这种痛苦

这是我的工作代码:

    [DllImport("gdi32.dll")]
    [return: MarshalAs(UnmanagedType.Bool)]
    internal static extern bool DeleteObject(IntPtr value);
    private void ReceiveImage()
    {
        BinaryFormatter binaryFormatter = new BinaryFormatter();
        System.Drawing.Image imgSrc;
        while (client.Connected)
        {

            var mainStream = client.GetStream();
            int loop = 0;
            while (!mainStream.DataAvailable && loop < 500)
            {
                loop++;
                Thread.Sleep(10);
            }
            if (mainStream.DataAvailable)
            {
                try
                {

                    imgSrc = (System.Drawing.Image)binaryFormatter.Deserialize(mainStream);
                    var bitmap = new Bitmap(imgSrc);
                    IntPtr bmpPt = bitmap.GetHbitmap();
                    BitmapSource bitmapSource =
                         System.Windows.Interop.Imaging.CreateBitmapSourceFromHBitmap(
                               bmpPt,
                               IntPtr.Zero,
                               Int32Rect.Empty,
                               BitmapSizeOptions.FromEmptyOptions());

                    //freeze bitmapSource and clear memory to avoid memory leaks
                    if (bitmapSource.CanFreeze && !bitmapSource.IsFrozen)
                        bitmapSource.Freeze();
                    DeleteObject(bmpPt);

                    if (displayImage.Dispatcher.CheckAccess())
                    {
                        displayImage.Source = bitmapSource;
                    }
                    else
                    {
                        Action act = () => { displayImage.Source = bitmapSource; };
                        displayImage.Dispatcher.BeginInvoke(act);
                    }
                }
                catch (Exception ex)
                {
                    Console.WriteLine(ex);
                }
            }
        }
    }

标签: wpftcpclientnetworkstream

解决方案


推荐阅读