C# 来自Bytearray的Xamarin图像-阻止流关闭?
对于我的Xamarin应用程序,我使用RESTAPI后端。 从后端我得到的图片是ByteArray 当我没有后端时,我通过C# 来自Bytearray的Xamarin图像-阻止流关闭?,c#,.net,xamarin,xamarin.forms,C#,.net,Xamarin,Xamarin.forms,对于我的Xamarin应用程序,我使用RESTAPI后端。 从后端我得到的图片是ByteArray 当我没有后端时,我通过 ImageSource.FromResource(..) 一切都很好。 有了ByteArray,我换成了 ImageSource.FromStream(..) 这在一开始也很管用。假设我在A页上显示一个图像。 当我从RESTAPI加载数据并填充ImageSource时,一切看起来都很好。 然后我通过Shell导航到B页,然后返回到A页 现在出现以下错误: System.
ImageSource.FromResource(..)
一切都很好。
有了ByteArray,我换成了
ImageSource.FromStream(..)
这在一开始也很管用。假设我在A页上显示一个图像。
当我从RESTAPI加载数据并填充ImageSource时,一切看起来都很好。
然后我通过Shell导航到B页,然后返回到A页
现在出现以下错误:
System.ObjectDisposedException: 'Cannot access a closed Stream.'
似乎流已关闭,这是正常的C行为。
但我想知道我现在能做些什么,这样我的应用程序在导航时不会崩溃。
当页面出现时,并不总是调用后端,因为可能会发生大量数据
我找到的唯一选择是将图片存储为base64字符串,当出现页面A时,我用新的流重新创建所有图像源。显然,这是糟糕的性能和糟糕的编码
有人知道我如何解决这个问题吗
如果您需要更多详细的代码或上下文,请发表评论
提前多谢!
编辑1
在IOS上它可以工作——只是在android上不行
编辑2
这肯定和贝壳有关
@Wendy Zang-MSFT的代码有效,谢谢!但如果我在shell中导航时尝试相同的代码,它就不会
还有其他想法吗?
这里是我用来测试的代码。您无法看到的是无法访问封闭流-发生错误
public partial class AboutPage : ContentPage
{
public byte[] ImageData { get; set; }
public AboutPage()
{
InitializeComponent();
}
private void Button_Clicked(object sender, EventArgs e)
{
using (WebClient client = new WebClient())
{
ImageData = client.DownloadData("https://aka.ms/campus.jpg");
}
var stream1 = new MemoryStream(ImageData);
image.Source = ImageSource.FromStream(() => stream1);
}
}
XAML:
结果:
我得到了从url下载的图像字节数组。然后将字节数组保存到imageData属性。当我导航到另一个页面时,可以看到没有错误的图像 xaml: 截图:
我得到了从url下载的图像字节数组。然后将字节数组保存到imageData属性。当我导航到另一个页面时,可以看到没有错误的图像 xaml: 截图:
如果您有完整的图像url,为什么不使用该url并将其绑定到您的ImageView如果您有完整的图像url,为什么不使用该url并将其绑定到您的ImageView调用函数时,流已经关闭。在传递给FromStream方法的函数内生成一个新流:
image.Source = ImageSource.FromStream(() => new MemoryStream(_imageData));
整个文件:
public partial class AboutPage : ContentPage
{
private byte[] _imageData;
public AboutPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
if (_imageData == null)
{
using (var client = new WebClient())
{
_imageData = client.DownloadData("https://aka.ms/campus.jpg");
}
}
image.Source = ImageSource.FromStream(() => new MemoryStream(_imageData));
}
}
调用函数时,流已关闭。在传递给FromStream方法的函数内生成一个新流:
image.Source = ImageSource.FromStream(() => new MemoryStream(_imageData));
整个文件:
public partial class AboutPage : ContentPage
{
private byte[] _imageData;
public AboutPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
if (_imageData == null)
{
using (var client = new WebClient())
{
_imageData = client.DownloadData("https://aka.ms/campus.jpg");
}
}
image.Source = ImageSource.FromStream(() => new MemoryStream(_imageData));
}
}
我也遇到了同样的问题,您必须在OnAppearing方法中初始化流 出现{var stream1=new时受保护的重写无效 MemoryStreamImageData;image.Source=ImageSource.FromStream=> stream1;}
我也遇到了同样的问题,您必须在OnAppearing方法中初始化流 出现{var stream1=new时受保护的重写无效 MemoryStreamImageData;image.Source=ImageSource.FromStream=> stream1;}
下载图像后将其缓存到磁盘。或者查看FFImageLoading,这将为您提供帮助。您可以尝试创建一个属性来存储ByteArray,然后将该属性设置为imageSource。@Jason我尝试了FFImageLoading对象,但没有成功,但可能是错误的对象?你指的是典型的缓存图像吗?如果没有,请给我一个提示,谢谢@温迪,我试过了。据我所知,如果不通过流进行转换,就不可能将字节数组作为图像源。我在OnPropertyChanged方法中执行了以下操作:var stream1=new MemoryStreamImageBytes;ItemImage.Source=ImageSource.FromStream=>stream1;但是仍然有相同的错误。下载图像后将其缓存到磁盘。或者查看FFImageLoading,这将为您提供帮助。您可以尝试创建一个属性来存储ByteArray,然后将该属性设置为imageSource。@Jason我尝试了FFImageLoading对象,但没有成功,但可能是错误的对象?你指的是典型的缓存图像吗?如果没有,请给我一个提示,谢谢@温迪,我试过了。据我所知,如果不通过流进行转换,就不可能将字节数组作为图像源。我在OnPropertyChanged方法中执行了以下操作:var stream1=new MemoryStreamImageBytes;ItemImage.Source=ImageSource.FromStream=>stream1;但仍然有相同的错误。谢谢你的工作!我对代码进行了测试,代码正常工作,但是当我使用shell导航时,错误就发生了。请参见上面的编辑。谢谢您的工作!我对代码进行了测试,代码运行正常,但是当我使用shell导航查看上面的编辑内容时,错误就发生了。这只是一个Exmaple。在真实情况下,我从后端得到的图片是bytearray,它只是一个Exmaple。在真实情况下,我从后端获得了bytearray的图片,谢谢,为我修复了它!谢谢,帮我修好了!
public partial class AboutPage : ContentPage
{
private byte[] _imageData;
public AboutPage()
{
InitializeComponent();
}
protected override void OnAppearing()
{
base.OnAppearing();
if (_imageData == null)
{
using (var client = new WebClient())
{
_imageData = client.DownloadData("https://aka.ms/campus.jpg");
}
}
image.Source = ImageSource.FromStream(() => new MemoryStream(_imageData));
}
}