c# - c# / Xamarin 相机插件
问题描述
我正在学习 C#,我正在尝试开发一个移动应用程序,用户可以在其中买卖东西。用户可以添加广告,其中一部分是他可以直接或从他自己的画廊捕捉照片。
我有完美运行的媒体插件,我失败的是能够在添加页面上临时存储和显示图片。我的目标是,一旦用户捕捉到一张照片,一旦他再次按下按钮拍照,它就会显示为 MainImage,上一张照片应该移动到 MainImage2 位置等等。主图像是最大的显示,所以一旦他捕捉到新照片他将有机会决定是否要为其做广告或拍摄不同的照片。
他总共应该能够拍摄 5 张照片并在他的广告中展示。
这是我的快速 xaml:
<?xml version="1.0" encoding="utf-8" ?>
<CarouselPage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:d="http://xamarin.com/schemas/2014/forms/design"
xmlns:mc="http://schemas.openxmlformats.org/markup-compatibility/2006"
mc:Ignorable="d"
xmlns:controls="clr-namespace:Baltazar.Controls"
xmlns:templates="clr-namespace:Baltazar.Views.Templates"
xmlns:resources="clr-namespace:Baltazar.Resources"
xmlns:helpers="clr-namespace:ImageCircle.Forms.Plugin.Abstractions;assembly=ImageCircle.Forms.Plugin"
xmlns:local="clr-namespace:Baltazar.Views"
x:Class="Baltazar.Views.AddingPage">
<ContentPage BackgroundColor="{ StaticResource BackgroundColor }">
<ContentPage.Content>
<StackLayout Spacing="-1">
<Grid Grid.Row="0" VerticalOptions="Start" RowSpacing="0">
<!--ToolBar-->
<Grid.RowDefinitions>
<RowDefinition Height="50"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>
<templates:HeaderItem Grid.Row="0"></templates:HeaderItem>
<AbsoluteLayout Grid.Row="0">
<!--Notifications-->
<Image Source ="{DynamicResource Notificatons}"
AbsoluteLayout.LayoutBounds="0.95,0.40,30,30"
AbsoluteLayout.LayoutFlags="XProportional,YProportional"
BackgroundColor= "Transparent">
</Image>
</AbsoluteLayout>
</Grid>
<Grid Grid.Row="1" RowSpacing="5" Padding="20,0,20,10">
<Grid.RowDefinitions>
<RowDefinition Height="Auto"/>
<RowDefinition Height="200"/>
<RowDefinition Height="Auto"/>
<RowDefinition Height="Auto"/>
</Grid.RowDefinitions>
<ProgressBar Grid.Row="0" IsVisible="True" BackgroundColor="Black" VerticalOptions="Start" HorizontalOptions="Center"/>
<Frame Padding="20,15,20,5" Grid.Row="1" HasShadow="True" HeightRequest="140" WidthRequest="100">
<Image x:Name="MainImage" Grid.Row="1"/>
</Frame>
<Grid Grid.Row="2" Padding="0,10,0,0">
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Frame HeightRequest="40" WidthRequest="43" Grid.Column="0">
<Image x:Name="MainImage1" Grid.Column="0"/>
</Frame>
<Frame HeightRequest="40" WidthRequest="43" Grid.Column="1">
<Image x:Name="retSource" Grid.Column="1"/>
</Frame>
<Frame HeightRequest="40" WidthRequest="43" Grid.Column="2">
<Image x:Name="MainImage3" Grid.Column="2"/>
</Frame>
<Frame HeightRequest="40" WidthRequest="43" Grid.Column="3">
<Image x:Name="MainImage4" Grid.Column="3"/>
</Frame>
<Frame HeightRequest="40" WidthRequest="43" Grid.Column="4">
<Image x:Name="MainImage5" Grid.Column="4"/>
</Frame>
</Grid>
<Grid Grid.Row="3" Padding="20,20,20,10">
<Grid.RowDefinitions>
<RowDefinition Height ="Auto"/>
<RowDefinition Height ="Auto"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="Auto"/>
<ColumnDefinition Width="Auto"/>
</Grid.ColumnDefinitions>
<Button Grid.Row="0" Grid.Column="0" Style ="{StaticResource SecondaryButton}" Text="{x:Static resources:LabelCZ.ButtonTakePicture}" Clicked="TakePicture_Clicked"/>
<Button Grid.Row="0" Grid.Column="1" Style ="{StaticResource SecondaryButton}" Text="{x:Static resources:LabelCZ.ButtonUploadPhoto}" Clicked="UploadPhoto_Clicked" />
<Button Grid.Row="1" Grid.Column="0" Style ="{StaticResource SecondaryButton}" Text="{x:Static resources:LabelCZ.ButtonTakeVideo}" Clicked="TakeVideo_Clicked" />
<Button Grid.Row="1" Grid.Column="1" Style ="{StaticResource SecondaryButton}" Text="{x:Static resources:LabelCZ.ButtonUploadVideo}" Clicked="UploadVideo_Clicked" />
</Grid>
</Grid>
</StackLayout>
</ContentPage.Content>
</ContentPage>
</CarouselPage>
这是背后的代码..
using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using System.Threading.Tasks;
using SQLite;
using Baltazar.Helpers;
using Baltazar.Model;
using Plugin.Media;
using Xamarin.Forms;
using Xamarin.Forms.Xaml;
using Plugin.Media.Abstractions;
using System.IO;
using System.Globalization;
namespace Baltazar.Views
{
[XamlCompilation(XamlCompilationOptions.Compile)]
public partial class AddingPage : CarouselPage
{
AdLogEntry adLogEntry = new AdLogEntry();
CameraService cameraService = new CameraService();
public byte[] imageAsBytes;
public string pathLabel;
public AddingPage()
{
InitializeComponent();
}
private async void TakePicture_Clicked(object sender, EventArgs e)
{
await CrossMedia.Current.Initialize();
if (!CrossMedia.Current.IsCameraAvailable || !CrossMedia.Current.IsTakePhotoSupported)
{
await DisplayAlert("Nemame přístup", "Nelze nalezt kameru", "OK");
return;
}
var file = await CrossMedia.Current.TakePhotoAsync(new Plugin.Media.Abstractions.StoreCameraMediaOptions
{
PhotoSize = Plugin.Media.Abstractions.PhotoSize.Medium,
Directory = "Sample",
SaveToAlbum = true,
Name = "test.jpg"
});
if (file == null)
return;
await DisplayAlert("File Location", file.Path, "OK");
pathLabel= file.Path;
MainImage.Source = ImageSource.FromStream(() => // display
{
var stream = file.GetStream();
return stream;
});
using (var memoryStream = new MemoryStream()) // image in bztes
{
file.GetStream().CopyTo(memoryStream);
file.Dispose();
imageAsBytes = memoryStream.ToArray();
}
}
public object Convert(object value, Type targetType, object parameter, CultureInfo culture)
{
ImageSource retSource = null;
if (value != null)
{
byte[] imageAsBytes = (byte[])value;
retSource = ImageSource.FromStream(() => new MemoryStream(imageAsBytes));
}
return retSource;
}
public void MovePicture()
{
if (retSource != null)
{
MainImage1.Source = retSource;
}
else
}
我的问题是,如果你能指出我正确的方向如何做到这一点。
解决方案
首先,你可以有一个模型:
public class User
{
public int Id {get; set;}
public string Name{get; set;}
public List<Picture> Pictures{get; set;}
}
public class Picture
{
public string Id {get; set;}
public string Url{get; set;}
public byte[] Image{get; set;}
}
现在您可以拥有一个带有它们的图片列表byte[]
,这样您就可以暂时显示它们。拍照后将图像添加到图片列表并更新您的 UI(您可以使用 MVVM 模式自动执行此操作)。
对于持久性,您可以使用 sqlite 进行本地存储,使用 azure 进行云存储。有大量的库可以轻松集成它。
希望这可以帮助。
推荐阅读
- python - 树莓派系统启动时自动 git pull
- java - 如果类具有私有构造函数,如何从 Java 配置而不是上下文 bean 创建 bean?
- php - 如何在不编辑第三方类的情况下将 PHP 方法添加到第三方类?
- python-2.7 - 使用 pycharm 的远程调试器时的 encodings.CodecRegistryError
- reactjs - 如何在模块化css React中更改fontawesome图标的颜色
- css - 控制列数
- html - HTML5 视频暂停而不是停止
- azure - Azure 应用程序网关 - 无法访问此站点
- javascript - 在构建我的 Vue 应用程序之前,我可以在哪里向生成的脚本标签添加属性?
- java - JPA/jHibernate 如何通知外部数据库更改?