NetMaui Android MemoryStreamClosedException при загрузке изображенийC#

Место общения программистов C#
Ответить
Anonymous
 NetMaui Android MemoryStreamClosedException при загрузке изображений

Сообщение Anonymous »

Я хочу загрузить изображения с телефона, обрезать их и сохранить с помощью HTTP-запроса. Для загрузки я определил следующий метод. При отладке я проверил, что все шаги метода работают и метод завершается как положено. Затем я привязываю изображение к своему представлению, но как только метод завершает работу, я получаю исключение ниже. Я установил точки останова в своей собственной реализации ImageCropper из DevExpress, но все, что там обрабатывает поток, никогда не вызывается. Кроме того, я также протестировал специальный инструмент для обрезки изображений, созданный с помощью SkiaSharp, который выдает то же исключение. Это все еще связано с этой проблемой?
https://github.com/dotnet/maui/issues/19230
ViewModel с методом UplaodImage:

Код: Выделить всё

public partial class DevExpressImageEditViewModel : BaseViewModel
{
// == bindable Properties ==
[ObservableProperty]
private byte[] _sourceImage;

[ObservableProperty]
private byte[] _editedImage;

[ObservableProperty]
private bool _editImage;

// == private fields ==
private readonly IPickerService _pickerService;
// == constructor ==
public DevExpressImageEditViewModel(INavigationService navigationService, PermissionState permissionState, ISystemClock systemClock, IPickerService pickerService) :
base(navigationService, permissionState, systemClock)
{
_pickerService = pickerService;
UploadImage();
}

// == RelayCommands ==
[RelayCommand]
public void CropImage()
{
EditImage = true;
}

// == public methods ==
public async Task UploadImage()
{
FileResult result = await _pickerService.PickAsync(new PickOptions
{
PickerTitle = "Choose Images",
FileTypes = FilePickerFileType.Images
});
if (result == null)
{
await _navigationService.NavigateToAsync("..");
return;
}

await using Stream up = await result.OpenReadAsync();
using MemoryStream stream = new MemoryStream();
await up.CopyToAsync(stream);
SourceImage = stream.ToArray();
}
Пользовательская реализация ImageEdit:

Код: Выделить всё

public class DevExpressImageEditImplementation : ImageEdit
{
// == Observable Properties ==
public static readonly BindableProperty SourceImageProperty = BindableProperty.Create(
nameof(SourceImage),
typeof(byte[]),
typeof(DevExpressImageEditImplementation),
null);
public static readonly BindableProperty EditedImageProperty = BindableProperty.Create(
nameof(EditedImage),
typeof(object),
typeof(DevExpressImageEditImplementation),
null);
public static readonly BindableProperty SaveTypeProperty = BindableProperty.Create(
nameof(SaveType),
typeof(ImageSaveType),
typeof(DevExpressImageEditImplementation),
ImageSaveType.ImageSource);

public static readonly BindableProperty ImageTypeProperty = BindableProperty.Create(
nameof(ImageType),
typeof(ImageFormat),
typeof(DevExpressImageEditImplementation),
ImageFormat.Jpeg);

public static readonly BindableProperty EditImageProperty = BindableProperty.Create(
nameof(EditImage),
typeof(bool),
typeof(DevExpressImageEditImplementation),
false,
propertyChanged: EditImageChanged);

// == properties ==
public byte[] SourceImage
{
get => (byte[])GetValue(SourceImageProperty);
set
{
SetValue(SourceImageProperty, value);
if(value == null)
return;
Source = ImageSource.FromStream(() => new MemoryStream(value));
EditedImage = SourceImage;
}
}

public object EditedImage
{
get => GetValue(EditedImageProperty);
set => SetValue(EditedImageProperty, value);
}

public ImageSaveType SaveType
{
get => (ImageSaveType)GetValue(SaveTypeProperty);
set => SetValue(SaveTypeProperty, value);
}

public bool EditImage
{
get => (bool)GetValue(EditImageProperty);
set => SetValue(EditImageProperty, value);
}

public ImageFormat ImageType
{
get => (ImageFormat)GetValue(ImageTypeProperty);
set =>  SetValue(ImageTypeProperty, value);
}

// == private methods ==
private static void EditImageChanged(BindableObject bindable, object oldvalue, object newvalue)
{
if (bindable is not DevExpressImageEditImplementation { EditImage: true } imageEdit)
{
return;
}

switch (imageEdit.SaveType)
{
case ImageSaveType.Base64:
{
imageEdit.EditedImage = imageEdit.SaveAsBase64(imageEdit.ImageType);
break;
}
case ImageSaveType.Stream:
{
using MemoryStream memoryStream = new MemoryStream();
imageEdit.SaveAsStream(memoryStream, imageEdit.ImageType);
imageEdit.EditedImage = memoryStream;
break;
}
case ImageSaveType.ImageSource:
{
imageEdit.EditedImage = imageEdit.SaveAsImageSource(imageEdit.ImageType);
break;
}
default:
return;
}

imageEdit.EditImage = false;
}
}
И использование в представлении: И, наконец, исключение:

Код: Выделить всё

System.ObjectDisposedException: Cannot access a closed Stream.
at System.IO.MemoryStream.EnsureNotClosed()
at System.IO.MemoryStream.Read(Byte[] buffer, Int32 offset, Int32 count)
at Android.Runtime.InputStreamAdapter.Read(Byte[] bytes, Int32 offset, Int32 length) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/InputStreamAdapter.cs:line 38
at Java.IO.InputStream.n_Read_arrayBII(IntPtr jnienv, IntPtr native__this, IntPtr native_b, Int32 off, Int32 len) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/obj/Release/net8.0/android-34/mcw/Java.IO.InputStream.cs:line 229
at Android.Runtime.JNINativeWrapper.Wrap_JniMarshal_PPLII_I(_JniMarshal_PPLII_I callback, IntPtr jnienv, IntPtr klazz, IntPtr p0, Int32 p1, Int32 p2) in /Users/runner/work/1/s/xamarin-android/src/Mono.Android/Android.Runtime/JNINativeWrapper.g.cs:line 275
В целом я понимаю, что означает это исключение, но поскольку оно относится конкретно к Android и я не могу точно определить его местоположение в своем коде, я не знаю, как его исправить. .

Подробнее здесь: https://stackoverflow.com/questions/787 ... ing-images
Ответить

Быстрый ответ

Изменение регистра текста: 
Смайлики
:) :( :oops: :roll: :wink: :muza: :clever: :sorry: :angel: :read: *x)
Ещё смайлики…
   
К этому ответу прикреплено по крайней мере одно вложение.

Если вы не хотите добавлять вложения, оставьте поля пустыми.

Максимально разрешённый размер вложения: 15 МБ.

Вернуться в «C#»