【问题标题】:Xam.Plugin.Media 'Too many open files'Xam.Plugin.Media '打开的文件太多'
【发布时间】:2017-12-11 16:17:38
【问题描述】:

我有一个使用 Xam.Plugin.Media 帮助程序的 Xamarin 表单 PCL 应用程序。我有一个页面,用户在按下按钮时调用相机助手来拍照。来自相机助手的字节返回到页面并用作图像的源。页面上有一个保存按钮,我基本上调用消息传递服务并将字节保存到 PCL SQlite 存储。问题是我获得了大约 3 次成功加载此页面,并且可以在使用相机拍摄图像之后但在它返回字节之前获得异常之前使用相机助手拍照。异常消息是“打开的文件太多”。这是针对 iOS 的。所有相关代码如下。谢谢

相机助手:

 public class CameraHelper
{
    private MediaFile file;

    public async Task<byte[]> TakePicture()
    {
        await CrossMedia.Current.Initialize();

        if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
        {
            throw new Exception("No camera available");
        }

       using (MediaFile file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
        {
            Name = $"photo{DateTime.Now.ToString("yyyyMMddHHmmss")}.jpg",
            PhotoSize = PhotoSize.Small,
            CompressionQuality = 80,
            AllowCropping = true,
        }))

        {
            if (file == null)
            {
                return null;
            }
            using (System.IO.Stream stream = file.GetStream())
            {
                ImgBytes = new byte[stream.Length];
                await stream.ReadAsync(ImgBytes, 0, Convert.ToInt32(stream.Length));
                file.Dispose();
            }
        }
        return ImgBytes;
    }
}

拍照页面:

 <ContentPage.Content>
    <StackLayout VerticalOptions="FillAndExpand" Padding="12,10,12,15">

        <Label x:Name="photoTypeLabel" Text="Take *photo type* Photo" VerticalOptions="Start" />

        <StackLayout Padding="0,30,0,70">

            <ffimageloading:CachedImage x:Name="Image" Grid.Row="0" FadeAnimationEnabled="true"  Aspect="AspectFill"
                                         HeightRequest="200" WidthRequest="125" >
                <ffimageloading:CachedImage.GestureRecognizers>
                    <TapGestureRecognizer Tapped="OnImageTapped" />
                </ffimageloading:CachedImage.GestureRecognizers>
            </ffimageloading:CachedImage>
        </StackLayout>

        <Label Grid.Row="0" Grid.Column="1"
               Text="{ x:Static local:GrialShapesFont.PhotoCamera }"
                Style="{StaticResource FontIcon}"
                HorizontalTextAlignment="Center"
                Opacity="1"
                FontSize="60"
                TextColor="#FF000000"
                VerticalOptions="Center"
                HorizontalOptions="Center">
            <Label.GestureRecognizers>
                <TapGestureRecognizer Tapped="OnCameraTapped" />
            </Label.GestureRecognizers>
        </Label>

        <Button Style="{StaticResource PrimaryActionButtonStyle}" VerticalOptions="End" Text="Save" WidthRequest="{ artina:OnOrientationDouble
                    LandscapePhone=200,
                    LandscapeTablet=400 }" HorizontalOptions="{ artina:OnOrientationLayoutOptions
                    PortraitPhone=Fill,
                    LandscapePhone=Center,
                    PortraitTablet=Fill,
                    LandscapeTablet=Center }" Clicked="saveButtonClicked" />

        <Button  Style="{StaticResource PrimaryActionButtonStyle}" VerticalOptions="End" Text="Cancel" WidthRequest="{ artina:OnOrientationDouble
                    LandscapePhone=200,
                    LandscapeTablet=400 }" HorizontalOptions="{ artina:OnOrientationLayoutOptions
                    PortraitPhone=Fill,
                    LandscapePhone=Center,
                    PortraitTablet=Fill,
                    LandscapeTablet=Center }"  Clicked="cancelButtonClicked" />
    </StackLayout>
</ContentPage.Content>

拍照页面代码后面:

  private async void OnCameraTapped(object sender, EventArgs args)
    {
        CameraHelper cameraHelper = new CameraHelper();

        try
        {
            ImgBytes = await cameraHelper.TakePicture();
            Image.Source = ImageSource.FromStream(() =>
            {
                return new MemoryStream(ImgBytes);
            });
        }
        catch (Exception ex)
        {
            if (ex.Message == "No camera available")
            {
                await DisplayAlert("Error", "No camera available", "Ok");
            }
            else
            {
                await DisplayAlert("Error", "Unable to take picture.", "Ok");
            }
        }
    }

【问题讨论】:

  • 更新了相机助手以反映第一个建议的答案

标签: xamarin xamarin.forms


【解决方案1】:

如果我正确读取the codeGetStream 每次都会打开一个新流到文件。我会尝试将您的 CrossMedia.Current.TakePhotoAsync 调用和流包装在 using 语句中,以确保它们得到正确处理。

public class CameraHelper
{
    public async Task<byte[]> TakePicture()
    {
        await CrossMedia.Current.Initialize();

        if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
        {
            throw new Exception("No camera available");
        }

        using ( MediaFile file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
        {
            Name = $"photo{DateTime.Now.ToString("yyyyMMddHHmmss")}.jpg",
            PhotoSize = PhotoSize.Small,
            CompressionQuality = 80,
            AllowCropping = true,

        }) ) {

            if (file == null) {
                return null;
            }
            using (System.IO.Stream stream = file.GetStream()) {
                byte[] ImgBytes;
                ImgBytes = new byte[stream.Length];
                stream.Read(ImgBytes, 0, Convert.ToInt32(stream.Length));
            }
        }
        return ImgBytes;
    }
}

【讨论】:

  • 谢谢,这看起来很有希望,但我仍然遇到同样的错误
  • 我确实检查过,这是唯一的地方。除非 ffimageloading 类型的图像从幕后的文件中加载?否则我只是使用来自相机助手的字节数组,没有别的
  • @PatrickGoode 您是否看到任何本机崩溃?都是托管堆栈跟踪吗?
猜你喜欢
  • 1970-01-01
  • 2012-05-09
  • 2011-07-18
  • 2019-10-30
  • 2011-01-03
  • 2011-08-05
  • 2014-03-31
  • 2017-03-03
相关资源
最近更新 更多