wpf - 图片框移植到 WPF
问题描述
我在将我picturebox
的 from移植Windows Form
到WPF
.
我的问题不在于它picturebox
本身,而是我在显示image
get from NetworkStream
from a Thread
into an Image
in时遇到了麻烦WPF
。
我NetworkStream
从TcpClient
连接客户端服务器得到这个。
这是我的 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);
}
}
}
}
解决方案
推荐阅读
- ios - SwiftUI 中的自定义范围滑块
- html - 伪元素在 3D 中不会落后于它的父元素
- git - 将旧版本的分支合并到当前分支?
- javascript - 不声明导入资产
- flutter - 如何通过颤振客户端添加 cc 用户。(不使用网络控制台)
- openlayers - 在 openlayers 中测量面积的例子是错误的吗?
- python - 使用 subprocess.Popen() 和手动在 shell 中运行命令之间的区别?
- java - 编写一个迭代算法递归,但我不明白我做错了什么
- regex - 在 Perl 中使用 SSH 编辑远程文件
- c++ - 如何使用非模板派生类制作非类型模板基类