Skip to content

Commit

Permalink
CaptureImageAsync method implemented
Browse files Browse the repository at this point in the history
  • Loading branch information
dimonovdd committed Jan 23, 2021
1 parent a034b94 commit 0746611
Show file tree
Hide file tree
Showing 22 changed files with 2,828 additions and 112 deletions.
26 changes: 13 additions & 13 deletions Xamarin.Forms.ViewToImage.sln → ImageFromXamamrinUI.sln
Original file line number Diff line number Diff line change
Expand Up @@ -11,7 +11,7 @@ Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample.iOS", "Sample\Sample
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Sample", "Sample\Sample\Sample.csproj", "{E3982452-E783-448F-B9CD-8246549F0D5F}"
EndProject
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "Xamarin.Forms.ViewToImage", "Sample.Xamarin.Forms.ViewToImage\Xamarin.Forms.ViewToImage.csproj", "{D4B822E2-80BE-4771-83E0-CF83B8D899D0}"
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "ImageFromXamarinUI", "ImageFromXamarinUI\ImageFromXamarinUI.csproj", "{6E301B89-554A-46B7-A0BA-A892171F0A3C}"
EndProject
Global
GlobalSection(SolutionConfigurationPlatforms) = preSolution
Expand Down Expand Up @@ -59,18 +59,18 @@ Global
{E3982452-E783-448F-B9CD-8246549F0D5F}.Debug|iPhone.Build.0 = Debug|Any CPU
{E3982452-E783-448F-B9CD-8246549F0D5F}.Release|iPhone.ActiveCfg = Release|Any CPU
{E3982452-E783-448F-B9CD-8246549F0D5F}.Release|iPhone.Build.0 = Release|Any CPU
{D4B822E2-80BE-4771-83E0-CF83B8D899D0}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{D4B822E2-80BE-4771-83E0-CF83B8D899D0}.Debug|Any CPU.Build.0 = Debug|Any CPU
{D4B822E2-80BE-4771-83E0-CF83B8D899D0}.Release|Any CPU.ActiveCfg = Release|Any CPU
{D4B822E2-80BE-4771-83E0-CF83B8D899D0}.Release|Any CPU.Build.0 = Release|Any CPU
{D4B822E2-80BE-4771-83E0-CF83B8D899D0}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{D4B822E2-80BE-4771-83E0-CF83B8D899D0}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{D4B822E2-80BE-4771-83E0-CF83B8D899D0}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{D4B822E2-80BE-4771-83E0-CF83B8D899D0}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{D4B822E2-80BE-4771-83E0-CF83B8D899D0}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{D4B822E2-80BE-4771-83E0-CF83B8D899D0}.Debug|iPhone.Build.0 = Debug|Any CPU
{D4B822E2-80BE-4771-83E0-CF83B8D899D0}.Release|iPhone.ActiveCfg = Release|Any CPU
{D4B822E2-80BE-4771-83E0-CF83B8D899D0}.Release|iPhone.Build.0 = Release|Any CPU
{6E301B89-554A-46B7-A0BA-A892171F0A3C}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
{6E301B89-554A-46B7-A0BA-A892171F0A3C}.Debug|Any CPU.Build.0 = Debug|Any CPU
{6E301B89-554A-46B7-A0BA-A892171F0A3C}.Release|Any CPU.ActiveCfg = Release|Any CPU
{6E301B89-554A-46B7-A0BA-A892171F0A3C}.Release|Any CPU.Build.0 = Release|Any CPU
{6E301B89-554A-46B7-A0BA-A892171F0A3C}.Debug|iPhoneSimulator.ActiveCfg = Debug|Any CPU
{6E301B89-554A-46B7-A0BA-A892171F0A3C}.Debug|iPhoneSimulator.Build.0 = Debug|Any CPU
{6E301B89-554A-46B7-A0BA-A892171F0A3C}.Release|iPhoneSimulator.ActiveCfg = Release|Any CPU
{6E301B89-554A-46B7-A0BA-A892171F0A3C}.Release|iPhoneSimulator.Build.0 = Release|Any CPU
{6E301B89-554A-46B7-A0BA-A892171F0A3C}.Debug|iPhone.ActiveCfg = Debug|Any CPU
{6E301B89-554A-46B7-A0BA-A892171F0A3C}.Debug|iPhone.Build.0 = Debug|Any CPU
{6E301B89-554A-46B7-A0BA-A892171F0A3C}.Release|iPhone.ActiveCfg = Release|Any CPU
{6E301B89-554A-46B7-A0BA-A892171F0A3C}.Release|iPhone.Build.0 = Release|Any CPU
EndGlobalSection
GlobalSection(SolutionProperties) = preSolution
HideSolutionNode = FALSE
Expand Down
Original file line number Diff line number Diff line change
@@ -1,46 +1,49 @@
<Project Sdk="MSBuild.Sdk.Extras/3.0.22">
<Project Sdk="MSBuild.Sdk.Extras/3.0.22">
<PropertyGroup>
<TargetFrameworks>netstandard2.0;Xamarin.iOS10;MonoAndroid80;MonoAndroid81;MonoAndroid90;MonoAndroid10.0;</TargetFrameworks>
<TargetFrameworks>netstandard2.0;Xamarin.iOS10;MonoAndroid90;MonoAndroid10.0;</TargetFrameworks>
<AssemblyName>Sample.Xamarin.Forms.ViewToImage</AssemblyName>
<RootNamespace>Sample.Xamarin.Forms.ViewToImage</RootNamespace>
<PackageId>Sample.Xamarin.Forms.ViewToImageTEst</PackageId>
<RootNamespace>ImageFromXamarinUI</RootNamespace>
<PackageId>ImageFromXamarinUI</PackageId>
<PackageIcon>icon.png</PackageIcon>
<Summary>Converter From Xamarin.Forms.View To Image</Summary>
<PackageTags>xamarin, ios, android, toolkit, xamarin.forms</PackageTags>
<Title>Sample.Xamarin.Forms.ViewToImage</Title>
<Description>Converter From Xamarin.Forms.View To Image</Description>
<Summary>Extension methods for capturing images from UI</Summary>
<PackageTags>xamarin, ios, android, toolkit, xamarin.forms, image, ui, screenshot</PackageTags>
<Title>ImageFromXamarinUI</Title>
<Description>Extension methods for capturing images from UI</Description>
<Product>$(AssemblyName) ($(TargetFramework))</Product>
<AssemblyVersion>1.0.0.0</AssemblyVersion>
<AssemblyFileVersion>1.0.0.0</AssemblyFileVersion>
<Version>1.0.0</Version>
<PackageVersion>1.0.0</PackageVersion>
<PackageVersion>1.0.0-pre1</PackageVersion>
<Authors>dimonovdd</Authors>
<Owners>dimonovdd</Owners>
<RepositoryUrl>https://github.com/dimonovdd/Xamarin.Forms.ViewToImage</RepositoryUrl>
<PackageReleaseNotes>See: https://github.com/dimonovdd/Xamarin.Forms.ViewToImage/releases</PackageReleaseNotes>
<RepositoryUrl>https://github.com/dimonovdd/ImageFromXamarinUI</RepositoryUrl>
<PackageReleaseNotes>See: https://github.com/dimonovdd/ImageFromXamarinUI/releases</PackageReleaseNotes>
<DefineConstants>$(DefineConstants);</DefineConstants>
<UseFullSemVerForNuGet>false</UseFullSemVerForNuGet>
<EnableDefaultCompileItems>false</EnableDefaultCompileItems>
<PackageLicenseFile>LICENSE</PackageLicenseFile>
<PackageRequireLicenseAcceptance>true</PackageRequireLicenseAcceptance>
<PackageProjectUrl>https://github.com/dimonovdd/Xamarin.Forms.ViewToImage</PackageProjectUrl>
<PackageProjectUrl>https://github.com/dimonovdd/ImageFromXamarinUI</PackageProjectUrl>
<DebugType>portable</DebugType>
<Configurations>Debug;Release</Configurations>
<DevelopmentDependency>true</DevelopmentDependency>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)'=='Debug' ">
<DebugSymbols>true</DebugSymbols>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Debug|AnyCPU' ">
<DocumentationFile>bin\Debug\netstandard2.0\ImageFromXamarinUI.xml</DocumentationFile>
</PropertyGroup>
<PropertyGroup Condition=" '$(Configuration)|$(Platform)' == 'Release|AnyCPU' ">
<DocumentationFile>bin\Release\netstandard2.0\ImageFromXamarinUI.xml</DocumentationFile>
</PropertyGroup>
<ItemGroup>
<None Include="..\LICENSE" PackagePath="" Pack="true" />
<None Include="..\icon.png" PackagePath="" Pack="true" />
<PackageReference Include="Xamarin.Build.TypeRedirector" Version="0.1.2-preview" PrivateAssets="all" />
<PackageReference Include="Xamarin.Forms" Version="4.4.0.991864" />
<Compile Include="**\*.shared.cs" />
<Compile Include="**\*.shared.*.cs" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard1.')) ">
<PackageReference Include="System.ValueTuple" Version="4.5.0" />
</ItemGroup>
<ItemGroup Condition=" $(TargetFramework.StartsWith('netstandard')) ">
<PackageReference Include="System.Numerics.Vectors" Version="4.5.0" />
<Compile Include="**\*.netstandard.cs" />
Expand Down
48 changes: 48 additions & 0 deletions ImageFromXamarinUI/VisualElementExtension.android.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,48 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Android.Graphics;
using Xamarin.Forms;
using Xamarin.Forms.Platform.Android;

namespace ImageFromXamarinUI
{
public static partial class VisualElementExtension
{
static async Task<Stream> PlatformCaptureImageAsync(VisualElement view)
{
using var bitmap = ViewToBitMap(GetNativeView(view));
var stream = await BitMapToStream(bitmap);
bitmap.Recycle();
return stream;
}

static Android.Views.View GetNativeView(VisualElement view)
{
var render = Platform.GetRenderer(view);

if (render == null)
throw new ArgumentException($"The {view} parameter does not have a render", nameof(view));

return render.View;
}

static Bitmap ViewToBitMap(Android.Views.View view)
{
var bitmap = Bitmap.CreateBitmap(view.Width, view.Height, Bitmap.Config.Argb8888);
using var canvas = new Canvas(bitmap);
canvas.DrawColor(Android.Graphics.Color.Transparent);
view.Draw(canvas);

return bitmap;
}

static async Task<Stream> BitMapToStream(Bitmap bitmap)
{
var ms = new MemoryStream();
await bitmap.CompressAsync(Bitmap.CompressFormat.Png, 100, ms).ConfigureAwait(false);
ms.Position = 0;
return ms;
}
}
}
46 changes: 46 additions & 0 deletions ImageFromXamarinUI/VisualElementExtension.ios.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using System;
using System.IO;
using System.Threading.Tasks;
using UIKit;
using Xamarin.Forms;
using Xamarin.Forms.Platform.iOS;

namespace ImageFromXamarinUI
{
public static partial class VisualElementExtension
{
static Task<Stream> PlatformCaptureImageAsync(VisualElement view)
{
Stream stream = null;
using (var image = ViewToUIImage(GetNativeView(view)))
stream = ImageToStream(image);
return Task.FromResult(stream);
}

static UIView GetNativeView(VisualElement view)
{
var render = Platform.GetRenderer(view);

if (render == null)
throw new ArgumentException($"The {view} parameter does not have a render", nameof(view));

return render.NativeView;
}

static UIImage ViewToUIImage(UIView view)
{
UIGraphics.BeginImageContextWithOptions(view.Frame.Size, false, UIScreen.MainScreen.Scale);
view.Layer.RenderInContext(UIGraphics.GetCurrentContext());
var image = UIGraphics.GetImageFromCurrentImageContext();
UIGraphics.EndImageContext();

return image;
}

static Stream ImageToStream(UIImage image)
{
var imageData = image.AsPNG();
return imageData.AsStream();
}
}
}
14 changes: 14 additions & 0 deletions ImageFromXamarinUI/VisualElementExtension.netstandard.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,14 @@
using System;
using System.IO;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace ImageFromXamarinUI
{
public static partial class VisualElementExtension
{
static Task<Stream> PlatformCaptureImageAsync(VisualElement view)
=> throw new NotImplementedException($"{nameof(CaptureImageAsync)} not supported on netstandart project");

}
}
15 changes: 15 additions & 0 deletions ImageFromXamarinUI/VisualElementExtension.shared.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,15 @@
using System.IO;
using System.Threading.Tasks;
using Xamarin.Forms;

namespace ImageFromXamarinUI
{
public static partial class VisualElementExtension
{
/// <summary>Captures an image from the current state of <paramref name="element"/></summary>
/// <param name="element">element to which the render was assigned</param>
/// <returns>Stream an image as png with transparency</returns>
public static async Task<Stream> CaptureImageAsync(this VisualElement element)
=> await PlatformCaptureImageAsync(element);
}
}
12 changes: 0 additions & 12 deletions Sample.Xamarin.Forms.ViewToImage/ViewExtension.android.cs

This file was deleted.

11 changes: 0 additions & 11 deletions Sample.Xamarin.Forms.ViewToImage/ViewExtension.ios.cs

This file was deleted.

12 changes: 0 additions & 12 deletions Sample.Xamarin.Forms.ViewToImage/ViewExtension.netstandard.cs

This file was deleted.

12 changes: 0 additions & 12 deletions Sample.Xamarin.Forms.ViewToImage/ViewExtension.shared.cs

This file was deleted.

1 change: 0 additions & 1 deletion Sample/Sample.Android/MainActivity.cs
Original file line number Diff line number Diff line change
Expand Up @@ -6,7 +6,6 @@
using Android.Views;
using Android.Widget;
using Android.OS;
using Sample.Xamarin.Forms.ViewToImage;

namespace Sample.Droid
{
Expand Down
Loading

0 comments on commit 0746611

Please sign in to comment.