xamarin Xam.Plugin.Media“打开的文件太多”

ctzwtxfj  于 2023-03-16  发布在  其他
关注(0)|答案(2)|浏览(357)

我有一个Xamarin表单PCL应用程序,使用Xam.Plugin.Media助手。2我有一个页面,用户可以在按下按钮时调用一个摄像头助手来拍照。3摄像头助手的字节返回到页面,并作为图像的源。4页面上有一个保存按钮,我基本上可以调用消息服务并将字节保存到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");
            }
        }
    }
kmbjn2e3

kmbjn2e31#

如果我没有阅读错代码,GetStream每次都会打开一个新的流,我会尝试将CrossMedia.Current.TakePhotoAsync调用和流 Package 在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;
    }
}
ndasle7k

ndasle7k2#

我建议你看到Xamarin Essential相机视图。你可以实现自己的自定义相机屏幕。
https://learn.microsoft.com/pt-br/xamarin/community-toolkit/views/cameraview?source=recommendations
然后你可以保存在本地存储的图像,只是保存在本地数据库的路径,或者如果你想可以保存在Base64字符串,但我不推荐。

相关问题