我有一个Xamarin表单PCL应用程序,使用Xam.Plugin.Media助手。我有一个页面,用户在按钮上调用摄像头助手来拍照。来自摄像头助手的字节返回到页面并充当图像的源。页面上有一个保存按钮,我基本上调用消息服务并将字节保存到PCL SQlite存储。问题是我得到了这个页面的3次成功加载,并且可以在我用相机拍摄图像之后但在它返回字节之前得到异常之前用相机助手拍照。异常消息是“打开的文件太多”'。这适用于iOS。所有相关代码如下。感谢
相机助手:
ERROR: argument of ROWS must not contain variables
拍摄照片页面:
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>
答案 0 :(得分:2)
如果我正确阅读the code,GetStream
每次都会打开一个新的文件流。我会尝试在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;
}
}