【发布时间】:2022-01-18 22:38:43
【问题描述】:
我有一个 Xamarin.Forms Android 应用,其中相关页面如下所示:
<Grid>
<ScrollView>
<StackLayout Orientation="Vertical" Padding="30,24,30,24" Spacing="10">
<Image x:Name="CapturedImage" Source="{Binding Capture}" HeightRequest="100" WidthRequest="100"/>
<Button Margin="0,10,0,0" Text="Capture photo"
Command="{Binding OpenCameraCommand}"
BackgroundColor="{StaticResource Primary}"
TextColor="White" />
<Label Text="{Binding Description}" />
</StackLayout>
</ScrollView>
</Grid>
我使用该按钮打开 Android 原生相机,它可以工作。在 ViewModel 中会发生以下情况:
public class CaptureViewModel : BaseViewModel
{
private string _description;
public string Description
{
get => _description;
set
{
_description = value;
OnPropertyChanged();
}
}
private ImageSource _capture;
public ImageSource Capture
{
get => _capture;
set
{
_capture = value;
Description = value.ToString();
OnPropertyChanged();
}
}
public ICommand OpenCameraCommand { get; }
public CaptureViewModel()
{
Title = "Capture";
OpenCameraCommand = new Command(OnExecute);
}
private async void OnExecute()
{
await TakePhotoAsync();
}
private async Task TakePhotoAsync()
{
var mpo = new MediaPickerOptions
{
Title = "test"
};
var photo = await MediaPicker.CapturePhotoAsync(mpo);
await LoadPhotoAsync(photo);
var image = await Image.FromFileAsync(Capture.ToString());
var client = await ImageAnnotatorClient.CreateAsync();
var textAnnotations = await client.DetectTextAsync(image);
foreach (var text in textAnnotations)
{
Description = text.Description;
}
}
private async Task LoadPhotoAsync(FileResult photo)
{
if (photo == null)
{
Capture = null;
return;
}
var path = Environment.GetFolderPath(Environment.SpecialFolder.Personal);
var newFile = Path.Combine(path, photo.FileName);
using (var stream = await photo.OpenReadAsync())
{
var newStream = File.OpenWrite(newFile);
await stream.CopyToAsync(newStream);
newStream.Close();
newStream.Dispose();
}
Capture = newFile;
}
}
我实际上想使用 VM 中看到的 ImageAnnotator,但在尝试获取捕获的图像进行处理时总是出错。
System.IO.DirectoryNotFoundException: '找不到路径“/File: /data/user/0/com.companyname.app2/files/df033720bb9646928a9626e25e116990.jpg”的一部分。'
我在 AndroidManifest.xml 中的权限如下所示:
<uses-sdk android:minSdkVersion="21" android:targetSdkVersion="30" />
<application android:label="App2.Android" android:theme="@style/MainTheme"></application>
<uses-permission android:name="android.permission.ACCESS_NETWORK_STATE" />
<uses-feature android:name="android.hardware.camera" android:required="false" />
<uses-permission android:name="android.permission.WRITE_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.READ_EXTERNAL_STORAGE" />
<uses-permission android:name="android.permission.CAMERA" />
<uses-permission android:name="android.permission.ACCESS_MEDIA_LOCATION" />
<uses-permission android:name="android.permission.MANAGE_EXTERNAL_STORAGE" />
我不知道还有什么问题,但我尝试了其他一些方法,但没有帮助。可能是什么问题?
编辑:顺便说一句,我可以在视图中看到 Capture。并且出于调试原因的标签也显示了路径(与图中相同)。
【问题讨论】:
-
哪个特定行导致了异常?您似乎使用的是文件 url,而不是路径
-
它在这一行崩溃:
var image = await Image.FromFileAsync(Capture.ToString());我不确定,如果它只是在调试器中显示 File:。 -
Capture是一个ImageSource,你为什么会认为Capture.ToString()会返回一个文件路径?为什么不使用photo获取路径? -
哦,你完全正确!我让它变得非常复杂和愚蠢。原来照片有 FullPath 并且可以正常工作 :) 谢谢 Jason,我是 Xamarin 的新手!
-
@ToolmakerSteve FuulPath 返回
/data/user/0/com.companyname.app2/cache/2203693cc04e0be7f4f024d5f9499e13/6e02a0d384b144d6bbe0f6d5d6b961df/654e035499b8467a9d4293daf82d77e9.jpg。将很快添加详细信息。
标签: xamarin.forms xamarin.android permissions google-vision