处理照片时如何阻止应用数据增长

时间:2019-04-21 15:58:04

标签: xamarin.forms

将其发布在Xamarin论坛上,但尚未获得反馈。 希望这里有人可以提供帮助。

我正在编写一个应用程序(Xamarin.Forms),允许用户拍摄照片(使用Xam.Plugin.Media),然后在列表视图中显示它们。 我注意到随着拍摄的每张照片,应用程序数据都在增长。我希望有人可以阐明问题所在。 我不希望将照片保存在设备上。 我目前仅在android上进行过测试。

我编写了一个示例应用程序来模拟问题。已采取的步骤以及要遵循的XAML和视图模型代码。

  1. 安装应用。
  2. 转到Android /设置/应用/ {AppName} /存储
  3. 应用数据现在约为10Mb,缓存小于1Mb。
  4. 启动应用,拍照,但不要按“确定”以确认拍照。
  5. 请注意,应用程序数据现在随着内存中照片的大小增加而增加。 (让我们使用5Mb,这会将应用程序数据提高到15Mb)
  6. 按“确定”确认拍摄的照片,然后将其添加到列表视图。
  7. 请注意,应用程序数据再次增加,大约与内存中照片的大小有关。 (再次为5Mb,使应用程序数据达到20Mb)
  8. 因此,每拍摄一张照片,应用程序数据就会增加,大约是所拍摄照片的大小的两倍,因此,使用一个月后,该应用程序将使用大部分设备存储空间。

我不确定是否缺少简单的东西,或者这是由于编码不正确造成的。 任何建议将不胜感激。

谢谢。

XAML:

<ContentPage.Content>
    <Grid RowSpacing="0" Margin="10,10,10,0">
        <Grid.RowDefinitions>
            <RowDefinition Height="70"/>
            <RowDefinition Height="Auto"/>
            <RowDefinition Height="*"/>
        </Grid.RowDefinitions>
        <Button Grid.Row="0" Text="Take Photo" Command="{Binding TakePhotoCommand}"/>
        <Label Grid.Row="1" Text="Photo List" HorizontalOptions="Center"/>
        <ListView Grid.Row="2" ItemsSource="{Binding PhotoList}" RowHeight="250">
            <ListView.ItemTemplate>
                <DataTemplate>
                    <ViewCell>
                        <Grid>
                            <Image Source="{Binding ImageSource}" Aspect="Fill" />
                        </Grid>
                    </ViewCell>
                </DataTemplate>
            </ListView.ItemTemplate>
        </ListView>
    </Grid>
</ContentPage.Content>

查看模型:

public class CameraVM : INotifyPropertyChanged
    {
        public event PropertyChangedEventHandler PropertyChanged;

        protected void OnPropertyChanged(string propertyName)
        {
            var handler = PropertyChanged;
            if (handler != null)
                handler(this, new PropertyChangedEventArgs(propertyName));
        }

        private ObservableCollection<MyPhoto> photoList {get;set;}
        public ObservableCollection<MyPhoto> PhotoList
        {
            get { return photoList; }
            set
            {
                if(value != photoList)
                {
                    photoList = value;
                    OnPropertyChanged("PhotoList");
                }
            }
        }

        public ICommand TakePhotoCommand { get; set; }
        public async void TakePhoto()
        {
            try
            {
                await CrossMedia.Current.Initialize();
                var mediaFile = await CrossMedia.Current.TakePhotoAsync(new StoreCameraMediaOptions() { });
                if (mediaFile == null)
                {
                    return;
                }

                PhotoList.Add(new MyPhoto()
                {
                    ImageSource = ImageSource.FromStream(() =>
                    {
                        Stream stream = mediaFile.GetStream();
                        mediaFile.Dispose();
                        return stream;
                    })
                });
            }
            catch (Exception ex)
            {
                throw ex;
            }
        }

        public CameraVM()
        {
            PhotoList = new ObservableCollection<MyPhoto>();

            TakePhotoCommand = new Command(() =>
            {
                TakePhoto();
            });
        }
    }

1 个答案:

答案 0 :(得分:0)

经过进一步调查,我发现将StoreCameraMediaOptions对象上的SaveMetaData和SaveToAlbum属性设置为false,然后在使用设备后将其从设备中删除时,应用程序数据仍然增加,但没有增加。在查看设备的一般内存使用情况时,我注意到用于默认相机应用程序的内存也很大。清除相机的内存后,我的应用程序的数据又回到了几千字节。我继续在我的应用程序上拍摄了一些照片,该应用程序的数据增长了(如预期的那样),但几个小时后又恢复到几千字节。我想设备会在一段时间后清除未使用应用程序的内存。

这是我的工作代码。我的应用程序将拍摄的照片上传到服务器,然后使用相关的URL在列表视图中显示该照片。这就是为什么我以后可以从设备中删除照片的原因。我怀疑如果您尝试显示使用从拍摄的照片中收集的ImageSource拍摄的照片,则删除照片后将不会显示该照片。

仅在android(Galaxy S8)上测试过

    await CrossMedia.Current.Initialize();
    StoreCameraMediaOptions storeCameraMediaOptions = new StoreCameraMediaOptions()
    {
        SaveMetaData = false,
        SaveToAlbum = false
    };

    MediaFile mediaFile = await CrossMedia.Current.TakePhotoAsync(storeCameraMediaOptions);
    if (mediaFile != null)
    {
        string base64String = Convert.ToBase64String(ULHelper.ToByteArray(mediaFile.GetStream()));

        // Logic to upload photo to server using base64String

        if (File.Exists(mediaFile.Path))
        {
            File.Delete(mediaFile.Path);
        }

        mediaFile.Dispose();
    }