我想用相机拍照并在我所在的页面上显示
所以我有一个ViewModel,我可以拍照并显示它
public class CamViewModel : MvxViewModel,
IMvxServiceConsumer<IInstalledMeter>,
IMvxServiceConsumer<ICamaraService>
{
public CamViewModel()
{
this.GetService<ICamaraService>().PhotoSavedEvent += PhotoSaved;
if (!String.IsNullOrEmpty(this.GetService<IInstalledMeter>().ImagePath))
{
ImagePath = this.GetService<IInstalledMeter>().ImagePath;
}
TakePicture();
}
private string _imagePath;
public string ImagePath
{
get { return _imagePath; }
set { _imagePath = value; FirePropertyChanged("ImagePath"); }
}
//Navigate back to InstallUnit
public IMvxCommand OpenCamaraCommand
{
get
{
return new MvxRelayCommand(TakePicture);
}
}
private void PhotoSaved(object sender, PhotoSavedResultEventArgs e)
{
ImagePath = e.ImagePath;
}
private void TakePicture()
{
this.GetService<ICamaraService>().TakePhoto();
}
}
这使用了一个CameraService,它可以拍摄照片并将图片保存在隔离的存储空间中(我知道,关注的分离很糟糕)
public class CamaraService : IMvxServiceConsumer<IMvxPictureChooserTask>, IMvxServiceConsumer<IMvxSimpleFileStoreService>, IMvxServiceConsumer<IInstalledMeter>, ICamaraService
{
private const int MaxPixelDimension = 1024;
private const int DefaultJpegQuality = 70;
public event EventHandler<PhotoSavedResultEventArgs> PhotoSavedEvent;
private void PhotoTaken(PhotoSavedResultEventArgs e)
{
if (PhotoSavedEvent != null)
{
PhotoSavedEvent(this, e);
}
}
public string ImagePath { get; set; }
public void TakePicture()
{
this.GetService<IMvxPictureChooserTask>().TakePicture(
MaxPixelDimension,
DefaultJpegQuality,
SavePicture,
() => { /* cancel is ignored */ });
}
public void TakePhoto()
{
TakePicture();
}
public void SavePicture(Stream image)
{
var newImage = Save(image);
if (newImage != "")
{
DeleteOldImage(this.GetService<IInstalledMeter>().ImagePath);
this.GetService<IInstalledMeter>().ImagePath = newImage;
PhotoTaken(new PhotoSavedResultEventArgs {ImagePath = newImage});
}
}
public void UpdateModel(string filename)
{
}
public void DeleteOldImage(string fileName)
{
try
{
if (String.IsNullOrEmpty(fileName)) return;
var fileService = this.GetService<IMvxSimpleFileStoreService>();
fileService.DeleteFile(fileName);
}
catch
{
}
}
public string Save(Stream stream)
{
try
{
var fileName = Guid.NewGuid().ToString();
var fileService = this.GetService<IMvxSimpleFileStoreService>();
fileName = Path.Combine("Image", fileName);
fileService.WriteFile(fileName, stream.CopyTo);
return fileName;
}
catch (ThreadAbortException)
{
throw;
}
catch (Exception exception)
{
return "";
}
}
}
Windows Phone上的视图显示图像
<Views:BaseCamView
x:Class="UI.WP7.Views.InstallMeter.CamView"
xmlns:Views="clr-namespace:UI.WP7.Views.InstallMeter"
xmlns="http://schemas.microsoft.com/winfx/2006/xaml/presentation"
xmlns:x="http://schemas.microsoft.com/winfx/2006/xaml"
xmlns:phone="clr-namespace:Microsoft.Phone.Controls;assembly=Microsoft.Phone"
xmlns:shell="clr-namespace:Microsoft.Phone.Shell;assembly=Microsoft.Phone"
xmlns:d="http://schemas.microsoft.com/expression/blend/2008"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
xmlns:nativeConverters="clr-namespace:UI.WP7.NativeConverters"
FontFamily="{StaticResource PhoneFontFamilyNormal}"
FontSize="{StaticResource PhoneFontSizeNormal}"
Foreground="{StaticResource PhoneForegroundBrush}"
SupportedOrientations="Portrait" Orientation="Portrait"
mc:Ignorable="d"
shell:SystemTray.IsVisible="True">
<Views:BaseCamView.Resources>
<nativeConverters:PathToImageConverter x:Name="PathToImageConverter" />
</Views:BaseCamView.Resources>
<!--LayoutRoot is the root grid where all page content is placed-->
<Grid x:Name="LayoutRoot" Background="Transparent">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<!--TitlePanel contains the name of the application and page title-->
<StackPanel Grid.Row="0" Margin="12,17,0,28">
<TextBlock Text="MY sdf" Style="{StaticResource PhoneTextNormalStyle}"/>
<TextBlock Text="{Binding ImagePath}" Margin="9,-7,0,0" Style="{StaticResource PhoneTextTitle1Style}"/>
</StackPanel>
<Image Grid.Row="1" Source="{Binding ImagePath, Converter={StaticResource PathToImageConverter}}" Height="200" Width="700" Stretch="Uniform" />
</Grid>
此视图使用转换器将路径转换为bitmapimage
public class PathToImageConverter : IValueConverter, IMvxServiceConsumer<IMvxSimpleFileStoreService>
{
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
byte[] contents = null;
try
{
var file = this.GetService();
file.TryReadBinaryFile((string)value, out contents);
}
catch (Exception)
{
// masked
}
if (contents == null)
return null;
using (var stream = new MemoryStream(contents))
{
var image = new BitmapImage();
image.SetSource(stream);
return image;
}
}
但是当我尝试拍照时,转换器中的这个位返回null
if (contents == null)
return null;
所以我认为这意味着图像不可访问/保存或文件名错误,但不确定错误发生的位置
答案 0 :(得分:0)
我认为你需要逐步调试照片代码。
您还可以尝试向Exception catch处理程序添加一些跟踪。
有一种猜测是,您的基于GUID的文件名包含无效字符 - 请参阅http://msdn.microsoft.com/en-us/library/system.io.path.getinvalidpathchars%28v=vs.95%29.aspx尝试使用Guid.ToString("N") + ".jpg"
获取稍微欠错的文件名
但实际上,您需要跟踪代码并找出错误发生的位置。