Skip to content
This repository was archived by the owner on May 15, 2024. It is now read-only.
Closed
Show file tree
Hide file tree
Changes from all commits
Commits
Show all changes
34 commits
Select commit Hold shift + click to select a range
819c6f9
init SaveToGalery
dimonovdd Jan 9, 2021
a5d1a9f
fixed typos
dimonovdd Jan 10, 2021
6cc65af
Merge branch 'main' into featureSaveToGalery
mattleibow Jan 15, 2021
be537b6
Merge branch 'main' into featureSaveToGalery
dimonovdd Jan 16, 2021
e78d168
Merge branch 'main' into featureSaveToGalery
dimonovdd Jan 24, 2021
797bc90
added SaveToGaleryTestPhoto.jpg
dimonovdd Jan 24, 2021
ebde333
implementation for creating photos albums on ios
dimonovdd Jan 24, 2021
b376239
implementation for saving images and video files with metada on ios
dimonovdd Jan 25, 2021
eaa70f2
Merge branch 'main' into featureSaveToGalery
dimonovdd Jan 26, 2021
7e358a5
- implementation for saving images and video files from filePath on ios
dimonovdd Jan 26, 2021
9743df7
- implementation for saving images and video files from byte array, f…
dimonovdd Jan 30, 2021
ba09fb3
init SaveToGalery
dimonovdd Jan 9, 2021
3fa012b
fixed typos
dimonovdd Jan 10, 2021
37f8c02
added SaveToGaleryTestPhoto.jpg
dimonovdd Jan 24, 2021
c8a35d6
implementation for creating photos albums on ios
dimonovdd Jan 24, 2021
9c83cd9
implementation for saving images and video files with metada on ios
dimonovdd Jan 25, 2021
702dbbf
- implementation for saving images and video files from filePath on ios
dimonovdd Jan 26, 2021
7e3b885
- implementation for saving images and video files from byte array, f…
dimonovdd Jan 30, 2021
b647ab9
Merge branch 'featureSaveToGalery' of https://github.com/dimonovdd/Es…
dimonovdd Jan 30, 2021
42396aa
added macos implementation
dimonovdd Jan 30, 2021
e914f8e
Merge branch 'main' into featureSaveToGalery
dimonovdd Feb 13, 2021
c53a910
- impl UWP
dimonovdd Feb 13, 2021
665b88a
cleanup android implementation
dimonovdd Feb 13, 2021
fe8ba32
changes for PHAuthorizationStatus.Limited (iOS)
dimonovdd Feb 14, 2021
d8b4045
Removed DATE_TAKEN from SaveAsync method on droid
dimonovdd Feb 19, 2021
ee6335b
Merge branch 'main' into featureSaveToGalery
dimonovdd Feb 19, 2021
4d919db
reset DeviceTests.Android.csproj
dimonovdd Feb 20, 2021
3d79bfb
Renaming from SaveToGallery to MediaGallery
dimonovdd Feb 28, 2021
8cee060
updating sample and adding sample media files
dimonovdd Feb 28, 2021
8f14db4
added test for Save to gallery
dimonovdd Feb 28, 2021
5d95923
removed the functionality for creating albums
dimonovdd Apr 11, 2021
b71de73
fix typos in MediaGallery Tests
dimonovdd Apr 14, 2021
b5d5a6e
add docs and fix uwp
dimonovdd Apr 22, 2021
c722861
Merge branch 'main' into featureSaveToGalery
dimonovdd Jul 12, 2021
File filter

Filter by extension

Filter by extension


Conversations
Failed to load comments.
Loading
Jump to
Jump to file
Failed to load files.
Loading
Diff view
Diff view
Binary file added Content/Media/baboon.png
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Content/Media/earth.mp4
Binary file not shown.
Binary file added Content/Media/lomonosov.jpg
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
Binary file added Content/Media/newtons_cradle.gif
Loading
Sorry, something went wrong. Reload?
Sorry, we cannot display this file.
Sorry, this file is invalid so it cannot be displayed.
3 changes: 2 additions & 1 deletion DeviceTests/DeviceTests.Shared/DeviceTests.Shared.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -28,7 +28,8 @@
<PackageReference Include="xunit.runner.devices" Version="2.5.25" />
<PackageReference Include="UnitTests.HeadlessRunner" Version="2.0.0" />
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<ProjectReference Include="..\..\Xamarin.Essentials\Xamarin.Essentials.csproj" />
<ProjectReference Include="..\..\Xamarin.Essentials\Xamarin.Essentials.csproj" />
<EmbeddedResource Include="..\..\Content\Media\*" Link="Media\%(Filename)%(Extension)" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('uap10.0')) ">
<PackageReference Include="Microsoft.NETCore.UniversalWindowsPlatform" Version="6.2.9" />
Expand Down
36 changes: 36 additions & 0 deletions DeviceTests/DeviceTests.Shared/MediaGallery_Tests.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,36 @@
using System.Linq;
using System.Reflection;
using System.Threading.Tasks;
using Xamarin.Essentials;
using Xunit;

namespace DeviceTests.Shared
{
public class MediaGallery_Tests
{
const string jpgName = "lomonosov.jpg";

[Fact]
[Trait(Traits.InteractionType, Traits.InteractionTypes.Human)]
public async Task SaveAsync()
{
var platform = DeviceInfo.Platform;
await MainThread.InvokeOnMainThreadAsync(async () =>
{
if (platform == DevicePlatform.iOS || platform == DevicePlatform.macOS)
await Permissions.RequestAsync<Permissions.Photos>();
else if (platform == DevicePlatform.Android)
await Permissions.RequestAsync<Permissions.StorageWrite>();
});

var assembly = typeof(MediaGallery_Tests).GetTypeInfo().Assembly;
var resourceName = assembly
.GetManifestResourceNames()
.FirstOrDefault(n => n.EndsWith(jpgName));

using var fileStream = assembly.GetManifestResourceStream(resourceName);

await MediaGallery.SaveAsync(MediaFileType.Image, fileStream, jpgName);
}
}
}
2 changes: 2 additions & 0 deletions Samples/Samples.Mac/Info.plist
Original file line number Diff line number Diff line change
Expand Up @@ -45,5 +45,7 @@
</array>
<key>NSContactsUsageDescription</key>
<string>Contacts</string>
<key>NSPhotoLibraryUsageDescription</key>
<string>Photos</string>
</dict>
</plist>
2 changes: 2 additions & 0 deletions Samples/Samples.UWP/Package.appxmanifest
Original file line number Diff line number Diff line change
Expand Up @@ -32,6 +32,8 @@
<Capabilities>
<Capability Name="internetClient" />
<uap:Capability Name="contacts"/>
<uap:Capability Name="picturesLibrary"/>
<uap:Capability Name="videosLibrary"/>
<DeviceCapability Name="location" />
<DeviceCapability Name="microphone"/>
<DeviceCapability Name="webcam"/>
Expand Down
6 changes: 3 additions & 3 deletions Samples/Samples/App.xaml.cs
Original file line number Diff line number Diff line change
Expand Up @@ -24,10 +24,10 @@ public partial class App : Application

public App()
{
InitializeComponent();

// Enable currently experimental features
Device.SetFlags(new string[] { "MediaElement_Experimental" });
Device.SetFlags(new string[] { "MediaElement_Experimental", "RadioButton_Experimental" });

InitializeComponent();

VersionTracking.Track();

Expand Down
44 changes: 44 additions & 0 deletions Samples/Samples/Helpers/EmbeddedResourceProvider.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,44 @@
using System.IO;
using System.Linq;
using System.Reflection;
using Xamarin.Forms;

namespace Samples.Helpers
{
public static class EmbeddedMedia
{
public const string baboonPng = "baboon.png";
public const string earthMp4 = "earth.mp4";
public const string lomonosovJpg = "lomonosov.jpg";
public const string newtonsCradleGif = "newtons_cradle.gif";
}

public static class EmbeddedResourceProvider
{
static readonly Assembly assembly = typeof(EmbeddedResourceProvider).GetTypeInfo().Assembly;
static readonly string[] resources = assembly.GetManifestResourceNames();

public static Stream Load(string name)
{
name = GetFullName(name);

if (string.IsNullOrWhiteSpace(name))
return null;

return assembly.GetManifestResourceStream(name);
}

public static ImageSource GetImageSource(string name)
{
name = GetFullName(name);

if (string.IsNullOrWhiteSpace(name))
return null;

return ImageSource.FromResource(name, assembly);
}

static string GetFullName(string name)
=> resources.FirstOrDefault(n => n.EndsWith($".Media.{name}"));
}
}
1 change: 1 addition & 0 deletions Samples/Samples/Samples.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -22,6 +22,7 @@

<ItemGroup>
<ProjectReference Include="..\..\Xamarin.Essentials\Xamarin.Essentials.csproj" />
<EmbeddedResource Include="..\..\Content\Media\*" Link="Media\%(Filename)%(Extension)" />
</ItemGroup>

</Project>
63 changes: 63 additions & 0 deletions Samples/Samples/View/MediaGalleryPage.xaml
Original file line number Diff line number Diff line change
@@ -0,0 +1,63 @@
<views:BasePage xmlns="http://xamarin.com/schemas/2014/forms"
xmlns:x="http://schemas.microsoft.com/winfx/2009/xaml"
xmlns:views="clr-namespace:Samples.View"
xmlns:viewmodels="clr-namespace:Samples.ViewModel"
x:Class="Samples.View.MediaGalleryPage"
x:DataType="viewmodels:MediaGalleryViewModel"
Title="Media Gallery">

<views:BasePage.BindingContext>
<viewmodels:MediaGalleryViewModel />
</views:BasePage.BindingContext>

<ScrollView>
<Grid RowSpacing="20" Padding="16">
<Grid.RowDefinitions>
<RowDefinition Height="auto"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="400"/>
<RowDefinition Height="auto"/>
<RowDefinition Height="*"/>
</Grid.RowDefinitions>

<Label Grid.Row="0" Text="Save To Gallery From:"
HorizontalTextAlignment="Center" FontAttributes="Bold" Margin="0"/>

<StackLayout Grid.Row="1" Orientation="Vertical" Margin="0" Padding="0" Spacing="8">
<RadioButton Text="Stream" IsChecked="{Binding FromStream}" Margin="0"/>
<RadioButton Text="ByteArray" IsChecked="{Binding FromByteArray}" Margin="0"/>
<RadioButton Text="CacheDirectory" IsChecked="{Binding FromCacheDirectory}" Margin="0"/>
</StackLayout>

<Grid Grid.Row="2" ColumnSpacing="8" RowSpacing="8">
<Grid.RowDefinitions>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
<RowDefinition Height="*"/>
<RowDefinition Height="40"/>
</Grid.RowDefinitions>
<Grid.ColumnDefinitions>
<ColumnDefinition Width="*"/>
<ColumnDefinition Width="*"/>
</Grid.ColumnDefinitions>

<Image Grid.Row="0" Grid.Column="0" Source="{Binding PngSource}"/>
<Button Grid.Row="1" Grid.Column="0" Text="Png" Command="{Binding SavevPngCommand}"/>

<Image Grid.Row="0" Grid.Column="1" Source="{Binding JpgSource}"/>
<Button Grid.Row="1" Grid.Column="1" Text="Jpg" Command="{Binding SaveJpgCommand}"/>


<Image Grid.Row="2" Grid.Column="0" Source="{Binding GifSource}"/>
<Button Grid.Row="3" Grid.Column="0" Text="Gif" Command="{Binding SaveGifCommand}"/>

<Label Grid.Row="2" Grid.Column="1" Text="Imagine a video of Earth here"
HorizontalTextAlignment="Center" VerticalTextAlignment="Center"/>
<Button Grid.Row="3" Grid.Column="1" Text="Video" Command="{Binding SaveVideoCommand}"/>
</Grid>

<Label Grid.Row="3" Text="Other features in the future"
HorizontalTextAlignment="Center" FontAttributes="Bold"/>
</Grid>
</ScrollView>
</views:BasePage>
10 changes: 10 additions & 0 deletions Samples/Samples/View/MediaGalleryPage.xaml.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
namespace Samples.View
{
public partial class MediaGalleryPage : BasePage
{
public MediaGalleryPage()
{
InitializeComponent();
}
}
}
6 changes: 6 additions & 0 deletions Samples/Samples/ViewModel/HomeViewModel.cs
Original file line number Diff line number Diff line change
Expand Up @@ -240,6 +240,12 @@ public HomeViewModel()
typeof(WebAuthenticatorPage),
"Quickly and easily authenticate and wait for a callback.",
new[] { "auth", "authenticate", "authenticator", "web", "webauth" }),
new SampleItem(
"🖼",
"Media Gallery",
typeof(MediaGalleryPage),
"Quickly and easily manage media files",
new[] { "save", "media", "gallery", "image", "video", "jpg", "png" })
};
filteredItems = samples;
filterText = string.Empty;
Expand Down
92 changes: 92 additions & 0 deletions Samples/Samples/ViewModel/MediaGalleryViewModel.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,92 @@
using System;
using System.IO;
using System.Net;
using System.Threading.Tasks;
using System.Windows.Input;
using Samples.Helpers;
using Xamarin.Essentials;
using Xamarin.Forms;

namespace Samples.ViewModel
{
public class MediaGalleryViewModel : BaseViewModel
{
public MediaGalleryViewModel()
{
SavevPngCommand = new Command(() => Save(MediaFileType.Image, EmbeddedMedia.baboonPng));
SaveJpgCommand = new Command(() => Save(MediaFileType.Image, EmbeddedMedia.lomonosovJpg));
SaveGifCommand = new Command(() => Save(MediaFileType.Image, EmbeddedMedia.newtonsCradleGif));
SaveVideoCommand = new Command(() => Save(MediaFileType.Video, EmbeddedMedia.earthMp4));

PngSource = EmbeddedResourceProvider.GetImageSource(EmbeddedMedia.baboonPng);
JpgSource = EmbeddedResourceProvider.GetImageSource(EmbeddedMedia.lomonosovJpg);
GifSource = EmbeddedResourceProvider.GetImageSource(EmbeddedMedia.newtonsCradleGif);
}

public bool FromStream { get; set; } = true;

public bool FromByteArray { get; set; }

public bool FromCacheDirectory { get; set; }

public ImageSource PngSource { get; }

public ImageSource JpgSource { get; }

public ImageSource GifSource { get; }

public ICommand SavevPngCommand { get; }

public ICommand SaveJpgCommand { get; }

public ICommand SaveGifCommand { get; }

public ICommand SaveVideoCommand { get; }

async void Save(MediaFileType type, string name)
{
try
{
using var stream = EmbeddedResourceProvider.Load(name);

if (FromStream)
{
await MediaGallery.SaveAsync(type, stream, name);
}
else if (FromByteArray)
{
using var memoryStream = new MemoryStream();
stream.CopyTo(memoryStream);

await MediaGallery.SaveAsync(type, memoryStream.ToArray(), name);
}
else if (FromCacheDirectory)
{
var filePath = SaveFileToCache(stream, name);

await MediaGallery.SaveAsync(type, filePath);
}

await DisplayAlertAsync("Save Completed Successfully");
}
catch (Exception ex)
{
await DisplayAlertAsync(ex.Message);
}
}

string SaveFileToCache(Stream data, string fileName)
{
var filePath = Path.Combine(FileSystem.CacheDirectory, fileName);

if (File.Exists(filePath))
File.Delete(filePath);

var stream = File.Create(filePath);
data.CopyTo(stream);
stream.Close();

return filePath;
}
}
}
Loading