Skip to content

Commit 134daa1

Browse files
Merge pull request #113 from DharanyaSakthivel-SF4210/master
ES-939872 - Added the AWS-EC2 sample in PPTX-to-Image conversion
2 parents be0b259 + e385cb7 commit 134daa1

File tree

8 files changed

+495
-0
lines changed

8 files changed

+495
-0
lines changed
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
2+
3+
# This stage is used when running from VS in fast mode (Default for Debug configuration)
4+
FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
5+
RUN apt-get update -y && apt-get install libfontconfig -y
6+
USER $APP_UID
7+
WORKDIR /app
8+
9+
10+
# This stage is used to build the service project
11+
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
12+
ARG BUILD_CONFIGURATION=Release
13+
WORKDIR /src
14+
COPY ["PPTXtoImage.csproj", "."]
15+
RUN dotnet restore "./PPTXtoImage.csproj"
16+
COPY . .
17+
WORKDIR "/src/."
18+
RUN dotnet build "./PPTXtoImage.csproj" -c $BUILD_CONFIGURATION -o /app/build
19+
20+
# This stage is used to publish the service project to be copied to the final stage
21+
FROM build AS publish
22+
ARG BUILD_CONFIGURATION=Release
23+
RUN dotnet publish "./PPTXtoImage.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
24+
25+
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
26+
FROM base AS final
27+
WORKDIR /app
28+
COPY --from=publish /app/publish .
29+
ENTRYPOINT ["dotnet", "PPTXtoImage.dll"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
9+
<DockerfileContext>.</DockerfileContext>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="AWSSDK.S3" Version="3.7.413.3" />
14+
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
15+
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.116.1" />
16+
<PackageReference Include="Syncfusion.PresentationRenderer.Net.Core" Version="*" />
17+
</ItemGroup>
18+
19+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.12.35707.178 d17.12
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PPTXtoImage", "PPTXtoImage.csproj", "{7BF3E653-F91B-46F4-AAF5-CB09B8DEC762}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{7BF3E653-F91B-46F4-AAF5-CB09B8DEC762}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{7BF3E653-F91B-46F4-AAF5-CB09B8DEC762}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{7BF3E653-F91B-46F4-AAF5-CB09B8DEC762}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{7BF3E653-F91B-46F4-AAF5-CB09B8DEC762}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
EndGlobal
Lines changed: 179 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,179 @@
1+
using Amazon.S3;
2+
using Amazon;
3+
using Amazon.S3.Model;
4+
using System;
5+
using System.IO;
6+
using System.Threading.Tasks;
7+
using Syncfusion.Presentation;
8+
using Syncfusion.PresentationRenderer;
9+
using SkiaSharp;
10+
11+
namespace PPTXtoImage
12+
{
13+
class Program
14+
{
15+
16+
private static readonly RegionEndpoint bucketRegion = RegionEndpoint.USEast1;
17+
private static IAmazonS3 s3Client;
18+
19+
static async Task Main()
20+
{
21+
var credentials = new Amazon.Runtime.BasicAWSCredentials("accessKey", "secretKey");
22+
var config = new AmazonS3Config
23+
{
24+
RegionEndpoint = bucketRegion
25+
};
26+
s3Client = new AmazonS3Client(credentials, config);
27+
28+
Console.WriteLine("Kindly enter the S3 bucket name: ");
29+
string bucketName = Console.ReadLine();
30+
Console.WriteLine("Kindly enter the input folder name that has the input PowerPoints: ");
31+
string inputFolderName = Console.ReadLine();
32+
Console.WriteLine("Kindly enter the output folder name in which the output images should be stored: ");
33+
string outputFolderName = Console.ReadLine();
34+
35+
//Gets the list of imput files from the input folder.
36+
List<string> inputFileNames = await ListFilesAsync(inputFolderName, bucketName);
37+
38+
for (int i = 0; i < inputFileNames.Count; i++)
39+
{
40+
//Converts PPTX to Image.
41+
await ConvertPptxToImage(inputFileNames[i], inputFolderName, bucketName, outputFolderName);
42+
}
43+
}
44+
/// <summary>
45+
/// Gets the list of input files.
46+
/// </summary>
47+
/// <returns></returns>
48+
private static async Task<List<string>> ListFilesAsync(string inputFolderName, string bucketName)
49+
{
50+
List<string> files = new List<string>();
51+
try
52+
{
53+
var request = new ListObjectsV2Request
54+
{
55+
BucketName = bucketName,
56+
Prefix = $"{inputFolderName}/",
57+
Delimiter = "/"
58+
};
59+
60+
ListObjectsV2Response response;
61+
do
62+
{
63+
response = await s3Client.ListObjectsV2Async(request);
64+
foreach (S3Object entry in response.S3Objects)
65+
{
66+
// Skip the "folder" itself
67+
if (entry.Key.EndsWith("/"))
68+
continue;
69+
70+
// Extract the filename by removing the folder path prefix
71+
string fileName = entry.Key.Substring(inputFolderName.Length);
72+
files.Add(fileName);
73+
}
74+
request.ContinuationToken = response.NextContinuationToken;
75+
} while (response.IsTruncated);
76+
return files;
77+
}
78+
catch (AmazonS3Exception e)
79+
{
80+
Console.WriteLine("Error encountered on server. Message:'{0}' when listing objects", e.Message);
81+
return null;
82+
}
83+
catch (Exception e)
84+
{
85+
Console.WriteLine("Unknown encountered on server. Message:'{0}' when listing objects", e.Message);
86+
return null;
87+
}
88+
}
89+
/// <summary>
90+
/// Converts the PPTX to the image.
91+
/// </summary>
92+
/// <param name="inputFileName">Input file name</param>
93+
/// <returns></returns>
94+
static async Task ConvertPptxToImage(string inputFileName, string inputFolderName, string bucketName, string outputFolderName)
95+
{
96+
try
97+
{
98+
//Download the file from S3 into the MemoryStream
99+
var response = await s3Client.GetObjectAsync(new Amazon.S3.Model.GetObjectRequest
100+
{
101+
BucketName = bucketName,
102+
Key = inputFolderName + inputFileName
103+
});
104+
using (Stream responseStream = response.ResponseStream)
105+
{
106+
MemoryStream fileStream = new MemoryStream();
107+
await responseStream.CopyToAsync(fileStream);
108+
//Open the existing PowerPoint presentation.
109+
using (IPresentation pptxDoc = Presentation.Open(fileStream))
110+
{
111+
//Initialize PresentationRenderer.
112+
pptxDoc.PresentationRenderer = new PresentationRenderer();
113+
//Convert the PowerPoint presentation as image streams.
114+
Stream[] images = pptxDoc.RenderAsImages(ExportImageFormat.Png);
115+
//Gets the file name without extension.
116+
string fileNameWithoutExt = Path.GetFileNameWithoutExtension(inputFileName);
117+
//Save the image streams to file.
118+
for (int i = 0; i < images.Length; i++)
119+
{
120+
using (Stream stream = images[i])
121+
{
122+
//Uploads the image to the S3 bucket.
123+
await UploadImageAsync(stream, $"{fileNameWithoutExt}" + i + ".png", bucketName, outputFolderName);
124+
}
125+
}
126+
}
127+
}
128+
}
129+
catch (AmazonS3Exception e)
130+
{
131+
Console.WriteLine($"Error encountered on server. Message:'{e.Message}'");
132+
}
133+
catch (Exception e)
134+
{
135+
Console.WriteLine($"Unknown error encountered. Message:'{e.Message}'");
136+
}
137+
}
138+
/// <summary>
139+
/// Uploads the image to the S3 bucket.
140+
/// </summary>
141+
/// <param name="imageStream">Converted image stream</param>
142+
/// <param name="outputFileName">Name that the image should be saved</param>
143+
/// <returns></returns>
144+
public static async Task UploadImageAsync(Stream imageStream, string outputFileName, string bucketName, string outputFolderName)
145+
{
146+
try
147+
{
148+
var key = $"{outputFolderName}/{outputFileName}"; // e.g., "images/your-image.png"
149+
150+
var request = new PutObjectRequest
151+
{
152+
BucketName = bucketName,
153+
Key = key,
154+
InputStream = imageStream,
155+
ContentType = "image/png" // Adjust based on your image type
156+
};
157+
158+
var response = await s3Client.PutObjectAsync(request);
159+
160+
if (response.HttpStatusCode == System.Net.HttpStatusCode.OK)
161+
{
162+
Console.WriteLine("Image uploaded successfully.");
163+
}
164+
else
165+
{
166+
Console.WriteLine($"Failed to upload image. HTTP Status Code: {response.HttpStatusCode}");
167+
}
168+
}
169+
catch (AmazonS3Exception ex)
170+
{
171+
Console.WriteLine($"Error encountered on server. Message:'{ex.Message}'");
172+
}
173+
catch (Exception ex)
174+
{
175+
Console.WriteLine($"Unknown error encountered. Message:'{ex.Message}'");
176+
}
177+
}
178+
}
179+
}
Lines changed: 29 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,29 @@
1+
# See https://aka.ms/customizecontainer to learn how to customize your debug container and how Visual Studio uses this Dockerfile to build your images for faster debugging.
2+
3+
# This stage is used when running from VS in fast mode (Default for Debug configuration)
4+
FROM mcr.microsoft.com/dotnet/runtime:8.0 AS base
5+
RUN apt-get update -y && apt-get install libfontconfig -y
6+
USER $APP_UID
7+
WORKDIR /app
8+
9+
10+
# This stage is used to build the service project
11+
FROM mcr.microsoft.com/dotnet/sdk:8.0 AS build
12+
ARG BUILD_CONFIGURATION=Release
13+
WORKDIR /src
14+
COPY ["PPTXtoImage.csproj", "."]
15+
RUN dotnet restore "./PPTXtoImage.csproj"
16+
COPY . .
17+
WORKDIR "/src/."
18+
RUN dotnet build "./PPTXtoImage.csproj" -c $BUILD_CONFIGURATION -o /app/build
19+
20+
# This stage is used to publish the service project to be copied to the final stage
21+
FROM build AS publish
22+
ARG BUILD_CONFIGURATION=Release
23+
RUN dotnet publish "./PPTXtoImage.csproj" -c $BUILD_CONFIGURATION -o /app/publish /p:UseAppHost=false
24+
25+
# This stage is used in production or when running from VS in regular mode (Default when not using the Debug configuration)
26+
FROM base AS final
27+
WORKDIR /app
28+
COPY --from=publish /app/publish .
29+
ENTRYPOINT ["dotnet", "PPTXtoImage.dll"]
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,19 @@
1+
<Project Sdk="Microsoft.NET.Sdk">
2+
3+
<PropertyGroup>
4+
<OutputType>Exe</OutputType>
5+
<TargetFramework>net8.0</TargetFramework>
6+
<ImplicitUsings>enable</ImplicitUsings>
7+
<Nullable>enable</Nullable>
8+
<DockerDefaultTargetOS>Linux</DockerDefaultTargetOS>
9+
<DockerfileContext>.</DockerfileContext>
10+
</PropertyGroup>
11+
12+
<ItemGroup>
13+
<PackageReference Include="AWSSDK.S3" Version="3.7.413.3" />
14+
<PackageReference Include="Microsoft.VisualStudio.Azure.Containers.Tools.Targets" Version="1.21.0" />
15+
<PackageReference Include="SkiaSharp.NativeAssets.Linux.NoDependencies" Version="3.116.1" />
16+
<PackageReference Include="Syncfusion.PresentationRenderer.Net.Core" Version="*" />
17+
</ItemGroup>
18+
19+
</Project>
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,22 @@
1+
2+
Microsoft Visual Studio Solution File, Format Version 12.00
3+
# Visual Studio Version 17
4+
VisualStudioVersion = 17.12.35707.178 d17.12
5+
MinimumVisualStudioVersion = 10.0.40219.1
6+
Project("{FAE04EC0-301F-11D3-BF4B-00C04F79EFBC}") = "PPTXtoImage", "PPTXtoImage.csproj", "{7BF3E653-F91B-46F4-AAF5-CB09B8DEC762}"
7+
EndProject
8+
Global
9+
GlobalSection(SolutionConfigurationPlatforms) = preSolution
10+
Debug|Any CPU = Debug|Any CPU
11+
Release|Any CPU = Release|Any CPU
12+
EndGlobalSection
13+
GlobalSection(ProjectConfigurationPlatforms) = postSolution
14+
{7BF3E653-F91B-46F4-AAF5-CB09B8DEC762}.Debug|Any CPU.ActiveCfg = Debug|Any CPU
15+
{7BF3E653-F91B-46F4-AAF5-CB09B8DEC762}.Debug|Any CPU.Build.0 = Debug|Any CPU
16+
{7BF3E653-F91B-46F4-AAF5-CB09B8DEC762}.Release|Any CPU.ActiveCfg = Release|Any CPU
17+
{7BF3E653-F91B-46F4-AAF5-CB09B8DEC762}.Release|Any CPU.Build.0 = Release|Any CPU
18+
EndGlobalSection
19+
GlobalSection(SolutionProperties) = preSolution
20+
HideSolutionNode = FALSE
21+
EndGlobalSection
22+
EndGlobal

0 commit comments

Comments
 (0)