我花了很长时间才找到这个答案的解决方案,如果微软向 ImageButton 添加一个方法来检索图像,那就太好了。在搜索了一段时间后,对数据类型更加熟悉,并查看了最初从用户那里获取图像时已经拥有的数据,我决定基本上扩展 ImageButton 控件以具有字节数组属性,并将其设置为用户选择图像时的属性。这让我很容易使用。我可以简单地从 ImageButton 访问字节数组,而不是从 ImageButton 获取图像作为某种随机数据类型,这是我需要的最终数据类型。
我是这样做的:在我从用户那里检索照片的方法中(改编自 Microsoft 示例的代码)
private async void ImgStudentImage_Clicked(object sender, EventArgs e)
{
Stream stream = await DependencyService.Get<IPhotoPickerService>().GetImageStreamAsync();
if (stream != null)
{
imgButton.Source = ImageSource.FromStream(() => stream);
}
}
服务返回一个流对象。流对象很有用,但使用起来有些笨拙。您可以看到我在此处的表单(页面)上分配了图像,但是当我尝试用它做任何其他事情时,图片会在表单上消失!所以我不能将流分配给 ImageButton 然后使用流创建一个字节数组 - 相当痛苦。解决方法是将流转换为字节数组并将该字节数组保存在我的 ExtendedImageButton 中,然后从存储在图像按钮中的字节数组中检索图像。傻吧?但它有效。所以我的 on_click 方法现在看起来像这样:
private async void ImgStudentImage_Clicked(object sender, EventArgs e)
{
Stream stream = await DependencyService.Get<IPhotoPickerService>().GetImageStreamAsync();
if (stream != null)
{
MemoryStream ms = new MemoryStream();
stream.CopyTo(ms); //this line causes the image on the form to disappear, no matter where the line is placed in code. Creating a copy of the stream doesn't solve the problem either.
imgButton.SourceAsByteArray = ms.ToArray();
imgButton.Source = Converters.ByteArrayToImageSource(imgButton.SourceAsByteArray);
}
}
我的 ExtendedImageButton 非常简单:
using Xamarin.Forms;
namespace MyNameSpace.Controls
{
class ExtendedImageButton : ImageButton
{
public byte[] SourceAsByteArray { get; set; }
}
}
如您所见,我刚刚添加了字节数组的属性。我将此文件存储在我的 Controls 文件夹中。在我的 xaml 中,我使用了这个参考和标签:
xmlns:controls="clr-namespace:MyAppName.Controls"
<controls:ExtendedImageButton />
我需要一种将字节数组转换回图像源的方法:
public static ImageSource ByteArrayToImageSource(byte[] byteArr)
{
Stream stream = new MemoryStream(byteArr);
return ImageSource.FromStream(() => stream);
}
我将此方法保存在一个名为“Converters”的类文件中。
最后,在我想从 ImageButton 中检索图像的代码中,我只需使用以下代码:
userPicture = imgButton.SourceAsByteArray;
其中 userPicture 当然是一个字节数组变量。