Select 并在 windows phone 中显示 xamarin.form.Image
Select and display xamarin.form.Image in windows phone
我正在使用 mvvmCross 在 Xamarin 中开发 Windows phone 8.1 的应用程序。我需要从 phone 库中 select 多个图像并显示它们。我正在使用 FileOpenPicker.SelectMultipleFilesAndContinue 这样做。现在我需要能够在视图中显示所有这些图像。一个问题是图像的最小数量必须为 20,并且图像可能非常大。
首先我尝试将它们制作成字节数组并使用转换器来显示它们。
public async void SelectFotosCallback(FileOpenPickerContinuationEventArgs args) {
if (args.Files.Count > 0) {
foreach (StorageFile file in args.Files) {
IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
byte[] bytes = null;
using (var reader = new DataReader(fileStream.GetInputStreamAt(0))) {
bytes = new byte[fileStream.Size];
await reader.LoadAsync((uint)fileStream.Size);
reader.ReadBytes(bytes);
}
callback(bytes);
}
}
else {
}
}
这个方法在第一次尝试时似乎确实有效,但当我用 5 张图像尝试它时,它就停止工作了。回调完成后,应用程序就退出了。没有错误消息或任何东西。 (我的猜测是内存过载。)
在此之后我找到了一个小解决方案,我将字节数组制作成 Xamarin.Form 图像。
public async void SelectFotosCallback(FileOpenPickerContinuationEventArgs args) {
if (args.Files.Count > 0) {
foreach (StorageFile file in args.Files) {
IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
byte[] bytes = null;
using (var reader = new DataReader(fileStream.GetInputStreamAt(0))) {
bytes = new byte[fileStream.Size];
await reader.LoadAsync((uint)fileStream.Size);
reader.ReadBytes(bytes);
}
Image image = new Image();
image.Source = ImageSource.FromStream(() => new MemoryStream(bytes));
var iets = image.Source.BindingContext;
callback(image);
}
}
else {
}
这似乎解决了内存过载的问题。现在唯一的另一个问题是我似乎找不到任何显示这些图像的方法。
<GridView ItemsSource="{Binding SelectedImages}">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<Image Style="{StaticResource imageListImage}" Source="{Binding Source}"/>
<Button Style="{StaticResource imageListXButton}">
<Button.Background>
<ImageBrush ImageSource="ms-appx:///Resources/XButton.png"/>
</Button.Background>
</Button>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
我尝试用简单的绑定来显示它们。我还没有找到任何可行的方法。有谁知道一种显示这些图像的方法,如果不知道,什么是使用字节而不使用太多内存的最佳替代方法。
经过深入挖掘,我找到了答案。这比我想象的要简单得多。我开始使用 BitmapImage 中的 decodepixel。我使用转换器设置值。
public object Convert(object value, Type targetType, object parameter, string language) {
BitmapImage image = (BitmapImage)value;
image.DecodePixelType = DecodePixelType.Logical;
if (image.PixelHeight >= image.PixelWidth) {
image.DecodePixelHeight = 100;
}
else {
image.DecodePixelWidth = 100;
}
return image;
}
奇怪的是它有时确实有效。但由于某种原因,它并没有对所有图像都起作用,有时甚至把它们扔掉了。
但是经过大量测试,我终于找到了我要找的东西。
BitmapImage bitmap = new BitmapImage();
BitmapImage temp = new BitmapImage();
bitmap.DecodePixelType = DecodePixelType.Logical;
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read)) {
IRandomAccessStream secondStream = fileStream.CloneStream();
BitmapImage temp = new BitmapImage();
temp.SetSource(fileStream);
if (temp.PixelHeight >= temp.PixelWidth) {
bitmap.DecodePixelHeight = 150;
}
else {
bitmap.DecodePixelWidth = 150;
}
bitmap.SetSource(secondStream);
}
出于某种原因,在设置源之后设置解码像素会导致不一致,但在设置源之前设置这些值实际上会立即裁剪图像。
这个方法非常有效,彻底解决了我的内存不足问题
我正在使用 mvvmCross 在 Xamarin 中开发 Windows phone 8.1 的应用程序。我需要从 phone 库中 select 多个图像并显示它们。我正在使用 FileOpenPicker.SelectMultipleFilesAndContinue 这样做。现在我需要能够在视图中显示所有这些图像。一个问题是图像的最小数量必须为 20,并且图像可能非常大。 首先我尝试将它们制作成字节数组并使用转换器来显示它们。
public async void SelectFotosCallback(FileOpenPickerContinuationEventArgs args) {
if (args.Files.Count > 0) {
foreach (StorageFile file in args.Files) {
IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
byte[] bytes = null;
using (var reader = new DataReader(fileStream.GetInputStreamAt(0))) {
bytes = new byte[fileStream.Size];
await reader.LoadAsync((uint)fileStream.Size);
reader.ReadBytes(bytes);
}
callback(bytes);
}
}
else {
}
}
这个方法在第一次尝试时似乎确实有效,但当我用 5 张图像尝试它时,它就停止工作了。回调完成后,应用程序就退出了。没有错误消息或任何东西。 (我的猜测是内存过载。)
在此之后我找到了一个小解决方案,我将字节数组制作成 Xamarin.Form 图像。
public async void SelectFotosCallback(FileOpenPickerContinuationEventArgs args) {
if (args.Files.Count > 0) {
foreach (StorageFile file in args.Files) {
IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read);
byte[] bytes = null;
using (var reader = new DataReader(fileStream.GetInputStreamAt(0))) {
bytes = new byte[fileStream.Size];
await reader.LoadAsync((uint)fileStream.Size);
reader.ReadBytes(bytes);
}
Image image = new Image();
image.Source = ImageSource.FromStream(() => new MemoryStream(bytes));
var iets = image.Source.BindingContext;
callback(image);
}
}
else {
}
这似乎解决了内存过载的问题。现在唯一的另一个问题是我似乎找不到任何显示这些图像的方法。
<GridView ItemsSource="{Binding SelectedImages}">
<GridView.ItemTemplate>
<DataTemplate>
<Grid>
<Image Style="{StaticResource imageListImage}" Source="{Binding Source}"/>
<Button Style="{StaticResource imageListXButton}">
<Button.Background>
<ImageBrush ImageSource="ms-appx:///Resources/XButton.png"/>
</Button.Background>
</Button>
</Grid>
</DataTemplate>
</GridView.ItemTemplate>
我尝试用简单的绑定来显示它们。我还没有找到任何可行的方法。有谁知道一种显示这些图像的方法,如果不知道,什么是使用字节而不使用太多内存的最佳替代方法。
经过深入挖掘,我找到了答案。这比我想象的要简单得多。我开始使用 BitmapImage 中的 decodepixel。我使用转换器设置值。
public object Convert(object value, Type targetType, object parameter, string language) {
BitmapImage image = (BitmapImage)value;
image.DecodePixelType = DecodePixelType.Logical;
if (image.PixelHeight >= image.PixelWidth) {
image.DecodePixelHeight = 100;
}
else {
image.DecodePixelWidth = 100;
}
return image;
}
奇怪的是它有时确实有效。但由于某种原因,它并没有对所有图像都起作用,有时甚至把它们扔掉了。 但是经过大量测试,我终于找到了我要找的东西。
BitmapImage bitmap = new BitmapImage();
BitmapImage temp = new BitmapImage();
bitmap.DecodePixelType = DecodePixelType.Logical;
using (IRandomAccessStream fileStream = await file.OpenAsync(Windows.Storage.FileAccessMode.Read)) {
IRandomAccessStream secondStream = fileStream.CloneStream();
BitmapImage temp = new BitmapImage();
temp.SetSource(fileStream);
if (temp.PixelHeight >= temp.PixelWidth) {
bitmap.DecodePixelHeight = 150;
}
else {
bitmap.DecodePixelWidth = 150;
}
bitmap.SetSource(secondStream);
}
出于某种原因,在设置源之后设置解码像素会导致不一致,但在设置源之前设置这些值实际上会立即裁剪图像。
这个方法非常有效,彻底解决了我的内存不足问题