diff --git a/FileConvertor/App.xaml.cs b/FileConvertor/App.xaml.cs
index c124263..316fbb1 100644
--- a/FileConvertor/App.xaml.cs
+++ b/FileConvertor/App.xaml.cs
@@ -61,8 +61,8 @@ private void ConfigureServices(IServiceCollection services)
services.AddSingleton
", "\n", RegexOptions.IgnoreCase);
+ html = Regex.Replace(html, @"
]*>(.*?)
", "$1\n\n", RegexOptions.Singleline | RegexOptions.IgnoreCase); + + // Convert line breaks + markdown = Regex.Replace(markdown, @"]*>(.*?)", "`$1`", RegexOptions.Singleline | RegexOptions.IgnoreCase);
+ markdown = Regex.Replace(markdown, @"]*>(.*?)", "```\n$1\n```\n", RegexOptions.Singleline | RegexOptions.IgnoreCase); + + // Remove remaining HTML tags + markdown = Regex.Replace(markdown, @"<[^>]+>", "", RegexOptions.Singleline); + + // Decode HTML entities + markdown = System.Net.WebUtility.HtmlDecode(markdown); + + // Clean up extra whitespace + markdown = Regex.Replace(markdown, @"\n{3,}", "\n\n"); + + return markdown.Trim(); + } + } +} diff --git a/FileConvertor/Core/Converters/IcoToPngConverter.cs b/FileConvertor/Core/Converters/IcoToPngConverter.cs new file mode 100644 index 0000000..5f8b3c9 --- /dev/null +++ b/FileConvertor/Core/Converters/IcoToPngConverter.cs @@ -0,0 +1,23 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Formats.Png; + +namespace FileConvertor.Core.Converters +{ + public class IcoToPngConverter : BaseConverter + { + public override string SourceFormat => "ico"; + public override string TargetFormat => "png"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + using var image = Image.Load(sourceStream); + image.Save(targetStream, new PngEncoder()); + }); + } + } +} diff --git a/FileConvertor/Core/Converters/JpgToGifConverter.cs b/FileConvertor/Core/Converters/JpgToGifConverter.cs new file mode 100644 index 0000000..92481cb --- /dev/null +++ b/FileConvertor/Core/Converters/JpgToGifConverter.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace FileConvertor.Core.Converters +{ + public class JpgToGifConverter : BaseConverter + { + public override string SourceFormat => "jpg"; + public override string TargetFormat => "gif"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + var decoder = new JpegBitmapDecoder(sourceStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); + var encoder = new GifBitmapEncoder(); + + encoder.Frames.Add(BitmapFrame.Create(decoder.Frames[0])); + encoder.Save(targetStream); + }); + } + } +} diff --git a/FileConvertor/Core/Converters/JpgToTiffConverter.cs b/FileConvertor/Core/Converters/JpgToTiffConverter.cs new file mode 100644 index 0000000..166e8d6 --- /dev/null +++ b/FileConvertor/Core/Converters/JpgToTiffConverter.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace FileConvertor.Core.Converters +{ + public class JpgToTiffConverter : BaseConverter + { + public override string SourceFormat => "jpg"; + public override string TargetFormat => "tiff"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + var decoder = new JpegBitmapDecoder(sourceStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); + var encoder = new TiffBitmapEncoder { Compression = TiffCompressOption.Zip }; + + encoder.Frames.Add(BitmapFrame.Create(decoder.Frames[0])); + encoder.Save(targetStream); + }); + } + } +} diff --git a/FileConvertor/Core/Converters/MkvToMp4Converter.cs b/FileConvertor/Core/Converters/MkvToMp4Converter.cs new file mode 100644 index 0000000..335c9e8 --- /dev/null +++ b/FileConvertor/Core/Converters/MkvToMp4Converter.cs @@ -0,0 +1,49 @@ +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Xabe.FFmpeg; + +namespace FileConvertor.Core.Converters +{ + public class MkvToMp4Converter : BaseConverter + { + public override string SourceFormat => "mkv"; + public override string TargetFormat => "mp4"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + var tempInput = Path.GetTempFileName(); + var tempOutput = Path.GetTempFileName(); + + try + { + using (var fileStream = File.Create(tempInput)) + { + await sourceStream.CopyToAsync(fileStream); + } + + var mediaInfo = await FFmpeg.GetMediaInfo(tempInput); + var conversion = FFmpeg.Conversions.New(); + + if (mediaInfo.VideoStreams.Any()) + conversion.AddStream(mediaInfo.VideoStreams.First()); + + if (mediaInfo.AudioStreams.Any()) + conversion.AddStream(mediaInfo.AudioStreams.First()); + + await conversion + .SetOutput(tempOutput) + .Start(); + + using var outputFile = File.OpenRead(tempOutput); + await outputFile.CopyToAsync(targetStream); + } + finally + { + if (File.Exists(tempInput)) File.Delete(tempInput); + if (File.Exists(tempOutput)) File.Delete(tempOutput); + } + } + } +} diff --git a/FileConvertor/Core/Converters/MovToMp4Converter.cs b/FileConvertor/Core/Converters/MovToMp4Converter.cs new file mode 100644 index 0000000..83ae331 --- /dev/null +++ b/FileConvertor/Core/Converters/MovToMp4Converter.cs @@ -0,0 +1,49 @@ +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Xabe.FFmpeg; + +namespace FileConvertor.Core.Converters +{ + public class MovToMp4Converter : BaseConverter + { + public override string SourceFormat => "mov"; + public override string TargetFormat => "mp4"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + var tempInput = Path.GetTempFileName(); + var tempOutput = Path.GetTempFileName(); + + try + { + using (var fileStream = File.Create(tempInput)) + { + await sourceStream.CopyToAsync(fileStream); + } + + var mediaInfo = await FFmpeg.GetMediaInfo(tempInput); + var conversion = FFmpeg.Conversions.New(); + + if (mediaInfo.VideoStreams.Any()) + conversion.AddStream(mediaInfo.VideoStreams.First()); + + if (mediaInfo.AudioStreams.Any()) + conversion.AddStream(mediaInfo.AudioStreams.First()); + + await conversion + .SetOutput(tempOutput) + .Start(); + + using var outputFile = File.OpenRead(tempOutput); + await outputFile.CopyToAsync(targetStream); + } + finally + { + if (File.Exists(tempInput)) File.Delete(tempInput); + if (File.Exists(tempOutput)) File.Delete(tempOutput); + } + } + } +} diff --git a/FileConvertor/Core/Converters/Mp3ToFlacConverter.cs b/FileConvertor/Core/Converters/Mp3ToFlacConverter.cs new file mode 100644 index 0000000..fe20d1e --- /dev/null +++ b/FileConvertor/Core/Converters/Mp3ToFlacConverter.cs @@ -0,0 +1,51 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using Xabe.FFmpeg; + +namespace FileConvertor.Core.Converters +{ + public class Mp3ToFlacConverter : BaseConverter + { + public override string SourceFormat => "mp3"; + public override string TargetFormat => "flac"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + // Create temporary files for FFmpeg + var tempInput = Path.GetTempFileName(); + var tempOutput = Path.GetTempFileName(); + + try + { + // Write source stream to temp file + using (var fileStream = File.Create(tempInput)) + { + await sourceStream.CopyToAsync(fileStream); + } + + // Convert using FFmpeg + var mediaInfo = await FFmpeg.GetMediaInfo(tempInput); + var audioStream = mediaInfo.AudioStreams.FirstOrDefault(); + + if (audioStream != null) + { + await FFmpeg.Conversions.New() + .AddStream(audioStream) + .SetOutput(tempOutput) + .Start(); + + // Copy result to target stream + using var outputFile = File.OpenRead(tempOutput); + await outputFile.CopyToAsync(targetStream); + } + } + finally + { + // Clean up temp files + if (File.Exists(tempInput)) File.Delete(tempInput); + if (File.Exists(tempOutput)) File.Delete(tempOutput); + } + } + } +} diff --git a/FileConvertor/Core/Converters/Mp4ToAviConverter.cs b/FileConvertor/Core/Converters/Mp4ToAviConverter.cs new file mode 100644 index 0000000..9052a05 --- /dev/null +++ b/FileConvertor/Core/Converters/Mp4ToAviConverter.cs @@ -0,0 +1,49 @@ +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Xabe.FFmpeg; + +namespace FileConvertor.Core.Converters +{ + public class Mp4ToAviConverter : BaseConverter + { + public override string SourceFormat => "mp4"; + public override string TargetFormat => "avi"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + var tempInput = Path.GetTempFileName(); + var tempOutput = Path.GetTempFileName(); + + try + { + using (var fileStream = File.Create(tempInput)) + { + await sourceStream.CopyToAsync(fileStream); + } + + var mediaInfo = await FFmpeg.GetMediaInfo(tempInput); + var conversion = FFmpeg.Conversions.New(); + + if (mediaInfo.VideoStreams.Any()) + conversion.AddStream(mediaInfo.VideoStreams.First()); + + if (mediaInfo.AudioStreams.Any()) + conversion.AddStream(mediaInfo.AudioStreams.First()); + + await conversion + .SetOutput(tempOutput) + .Start(); + + using var outputFile = File.OpenRead(tempOutput); + await outputFile.CopyToAsync(targetStream); + } + finally + { + if (File.Exists(tempInput)) File.Delete(tempInput); + if (File.Exists(tempOutput)) File.Delete(tempOutput); + } + } + } +} diff --git a/FileConvertor/Core/Converters/OggToMp3Converter.cs b/FileConvertor/Core/Converters/OggToMp3Converter.cs new file mode 100644 index 0000000..6eba620 --- /dev/null +++ b/FileConvertor/Core/Converters/OggToMp3Converter.cs @@ -0,0 +1,24 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using NAudio.Wave; +using NAudio.Lame; + +namespace FileConvertor.Core.Converters +{ + public class OggToMp3Converter : BaseConverter + { + public override string SourceFormat => "ogg"; + public override string TargetFormat => "mp3"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + using var reader = new StreamMediaFoundationReader(sourceStream); + using var writer = new LameMP3FileWriter(targetStream, reader.WaveFormat, 128); + reader.CopyTo(writer); + }); + } + } +} diff --git a/FileConvertor/Core/Converters/PdfToMarkdownConverter.cs b/FileConvertor/Core/Converters/PdfToMarkdownConverter.cs new file mode 100644 index 0000000..1ff4f74 --- /dev/null +++ b/FileConvertor/Core/Converters/PdfToMarkdownConverter.cs @@ -0,0 +1,50 @@ +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using UglyToad.PdfPig; + +namespace FileConvertor.Core.Converters +{ + public class PdfToMarkdownConverter : BaseConverter + { + public override string SourceFormat => "pdf"; + public override string TargetFormat => "md"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + var memoryStream = new MemoryStream(); + sourceStream.CopyTo(memoryStream); + memoryStream.Position = 0; + + var markdown = new StringBuilder(); + + using (var document = PdfDocument.Open(memoryStream)) + { + for (var i = 1; i <= document.NumberOfPages; i++) + { + var page = document.GetPage(i); + var text = page.Text; + + // Add page separator + if (i > 1) + { + markdown.AppendLine("\n---\n"); + } + + // Add page content + markdown.AppendLine($"## Page {i}\n"); + markdown.AppendLine(text); + } + } + + // Write markdown to stream + using var writer = new StreamWriter(targetStream, Encoding.UTF8); + writer.Write(markdown.ToString()); + writer.Flush(); + }); + } + } +} diff --git a/FileConvertor/Core/Converters/PngToGifConverter.cs b/FileConvertor/Core/Converters/PngToGifConverter.cs new file mode 100644 index 0000000..04fa67c --- /dev/null +++ b/FileConvertor/Core/Converters/PngToGifConverter.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace FileConvertor.Core.Converters +{ + public class PngToGifConverter : BaseConverter + { + public override string SourceFormat => "png"; + public override string TargetFormat => "gif"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + var decoder = new PngBitmapDecoder(sourceStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); + var encoder = new GifBitmapEncoder(); + + encoder.Frames.Add(BitmapFrame.Create(decoder.Frames[0])); + encoder.Save(targetStream); + }); + } + } +} diff --git a/FileConvertor/Core/Converters/PngToIcoConverter.cs b/FileConvertor/Core/Converters/PngToIcoConverter.cs new file mode 100644 index 0000000..4001d4f --- /dev/null +++ b/FileConvertor/Core/Converters/PngToIcoConverter.cs @@ -0,0 +1,35 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Formats.Ico; +using SixLabors.ImageSharp.Processing; + +namespace FileConvertor.Core.Converters +{ + public class PngToIcoConverter : BaseConverter + { + public override string SourceFormat => "png"; + public override string TargetFormat => "ico"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + using var image = Image.Load(sourceStream); + + // Resize to standard icon sizes if needed + if (image.Width > 256 || image.Height > 256) + { + image.Mutate(x => x.Resize(new ResizeOptions + { + Size = new Size(256, 256), + Mode = ResizeMode.Max + })); + } + + image.Save(targetStream, new IcoEncoder()); + }); + } + } +} diff --git a/FileConvertor/Core/Converters/PngToTiffConverter.cs b/FileConvertor/Core/Converters/PngToTiffConverter.cs new file mode 100644 index 0000000..d3bda45 --- /dev/null +++ b/FileConvertor/Core/Converters/PngToTiffConverter.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace FileConvertor.Core.Converters +{ + public class PngToTiffConverter : BaseConverter + { + public override string SourceFormat => "png"; + public override string TargetFormat => "tiff"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + var decoder = new PngBitmapDecoder(sourceStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); + var encoder = new TiffBitmapEncoder { Compression = TiffCompressOption.Zip }; + + encoder.Frames.Add(BitmapFrame.Create(decoder.Frames[0])); + encoder.Save(targetStream); + }); + } + } +} diff --git a/FileConvertor/Core/Converters/RtfToDocxConverter.cs b/FileConvertor/Core/Converters/RtfToDocxConverter.cs new file mode 100644 index 0000000..6bdfa65 --- /dev/null +++ b/FileConvertor/Core/Converters/RtfToDocxConverter.cs @@ -0,0 +1,98 @@ +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using DocumentFormat.OpenXml; +using DocumentFormat.OpenXml.Packaging; +using DocumentFormat.OpenXml.Wordprocessing; + +namespace FileConvertor.Core.Converters +{ + public class RtfToDocxConverter : BaseConverter + { + public override string SourceFormat => "rtf"; + public override string TargetFormat => "docx"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + // Read RTF content + using var reader = new StreamReader(sourceStream, Encoding.Default); + string rtfContent = reader.ReadToEnd(); + + // Strip RTF formatting to get plain text + string plainText = StripRtfFormatting(rtfContent); + + // Create DOCX + using var wordDocument = WordprocessingDocument.Create(targetStream, WordprocessingDocumentType.Document); + wordDocument.AddMainDocumentPart(); + var mainPart = wordDocument.MainDocumentPart!; + + mainPart.Document = new Document(); + var body = new Body(); + + // Add paragraphs + var lines = plainText.Split(new[] { '\r', '\n' }, StringSplitOptions.RemoveEmptyEntries); + foreach (var line in lines) + { + var paragraph = new Paragraph(); + var run = new Run(); + run.Append(new Text(line)); + paragraph.Append(run); + body.Append(paragraph); + } + + mainPart.Document.Append(body); + mainPart.Document.Save(); + }); + } + + private string StripRtfFormatting(string rtf) + { + if (string.IsNullOrEmpty(rtf)) + return string.Empty; + + var sb = new StringBuilder(); + bool inControl = false; + + for (int i = 0; i < rtf.Length; i++) + { + char c = rtf[i]; + + if (c == '\\') + { + inControl = true; + if (i + 1 < rtf.Length) + { + char next = rtf[i + 1]; + if (next == '\\' || next == '{' || next == '}') + { + sb.Append(next); + i++; + inControl = false; + } + } + } + else if (c == '{' || c == '}') + { + inControl = false; + } + else if (c == ' ' || c == '\n' || c == '\r') + { + if (!inControl) + { + sb.Append(c); + } + inControl = false; + } + else if (!inControl) + { + sb.Append(c); + } + } + + return sb.ToString().Trim(); + } + } +} diff --git a/FileConvertor/Core/Converters/RtfToPdfConverter.cs b/FileConvertor/Core/Converters/RtfToPdfConverter.cs new file mode 100644 index 0000000..898be21 --- /dev/null +++ b/FileConvertor/Core/Converters/RtfToPdfConverter.cs @@ -0,0 +1,105 @@ +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using iText.Kernel.Pdf; +using iText.Layout; +using iText.Layout.Element; +using iText.Kernel.Font; +using iText.IO.Font.Constants; + +namespace FileConvertor.Core.Converters +{ + public class RtfToPdfConverter : BaseConverter + { + public override string SourceFormat => "rtf"; + public override string TargetFormat => "pdf"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + // Read RTF content + using var reader = new StreamReader(sourceStream, Encoding.Default); + string rtfContent = reader.ReadToEnd(); + + // Strip RTF formatting to get plain text (basic implementation) + string plainText = StripRtfFormatting(rtfContent); + + // Create PDF + using var writer = new PdfWriter(targetStream); + writer.SetCloseStream(false); + using var pdf = new PdfDocument(writer); + using var document = new Document(pdf); + + var font = PdfFontFactory.CreateFont(StandardFonts.HELVETICA); + var paragraph = new Paragraph(plainText) + .SetFont(font) + .SetFontSize(12); + + document.Add(paragraph); + }); + } + + private string StripRtfFormatting(string rtf) + { + if (string.IsNullOrEmpty(rtf)) + return string.Empty; + + var sb = new StringBuilder(); + bool inControl = false; + bool inGroup = false; + + for (int i = 0; i < rtf.Length; i++) + { + char c = rtf[i]; + + if (c == '\\') + { + inControl = true; + // Check for special characters + if (i + 1 < rtf.Length) + { + char next = rtf[i + 1]; + if (next == '\\' || next == '{' || next == '}') + { + sb.Append(next); + i++; + inControl = false; + } + } + } + else if (c == '{') + { + inGroup = true; + inControl = false; + } + else if (c == '}') + { + inGroup = false; + inControl = false; + } + else if (c == ' ' || c == '\n' || c == '\r') + { + if (inControl) + { + inControl = false; + } + else if (!inGroup || rtf[i - 1] == '}') + { + if (c == '\n' || c == '\r') + sb.Append(' '); + else + sb.Append(c); + } + } + else if (!inControl) + { + sb.Append(c); + } + } + + return sb.ToString().Trim(); + } + } +} diff --git a/FileConvertor/Core/Converters/RtfToTextConverter.cs b/FileConvertor/Core/Converters/RtfToTextConverter.cs new file mode 100644 index 0000000..2057644 --- /dev/null +++ b/FileConvertor/Core/Converters/RtfToTextConverter.cs @@ -0,0 +1,93 @@ +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; + +namespace FileConvertor.Core.Converters +{ + public class RtfToTextConverter : BaseConverter + { + public override string SourceFormat => "rtf"; + public override string TargetFormat => "txt"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + // Read RTF content + using var reader = new StreamReader(sourceStream, Encoding.Default); + string rtfContent = reader.ReadToEnd(); + + // Strip RTF formatting to get plain text + string plainText = StripRtfFormatting(rtfContent); + + // Write plain text + using var writer = new StreamWriter(targetStream, Encoding.UTF8); + writer.Write(plainText); + writer.Flush(); + }); + } + + private string StripRtfFormatting(string rtf) + { + if (string.IsNullOrEmpty(rtf)) + return string.Empty; + + var sb = new StringBuilder(); + bool inControl = false; + bool inGroup = false; + + for (int i = 0; i < rtf.Length; i++) + { + char c = rtf[i]; + + if (c == '\\') + { + inControl = true; + // Handle escaped characters + if (i + 1 < rtf.Length) + { + char next = rtf[i + 1]; + if (next == '\\' || next == '{' || next == '}') + { + sb.Append(next); + i++; + inControl = false; + } + else if (next == 'p' && i + 3 < rtf.Length && rtf.Substring(i, 4) == "\\par") + { + sb.AppendLine(); + i += 3; + inControl = false; + } + } + } + else if (c == '{') + { + inGroup = true; + inControl = false; + } + else if (c == '}') + { + inGroup = false; + inControl = false; + } + else if (c == ' ' || c == '\n' || c == '\r') + { + if (!inControl) + { + if (c != '\r' && c != '\n') + sb.Append(c); + } + inControl = false; + } + else if (!inControl) + { + sb.Append(c); + } + } + + return sb.ToString().Trim(); + } + } +} diff --git a/FileConvertor/Core/Converters/TextToDocxConverter.cs b/FileConvertor/Core/Converters/TextToDocxConverter.cs new file mode 100644 index 0000000..cc3374e --- /dev/null +++ b/FileConvertor/Core/Converters/TextToDocxConverter.cs @@ -0,0 +1,45 @@ +using System; +using System.IO; +using System.Text; +using System.Threading.Tasks; +using DocumentFormat.OpenXml; +using DocumentFormat.OpenXml.Packaging; +using DocumentFormat.OpenXml.Wordprocessing; + +namespace FileConvertor.Core.Converters +{ + public class TextToDocxConverter : BaseConverter + { + public override string SourceFormat => "txt"; + public override string TargetFormat => "docx"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + using var reader = new StreamReader(sourceStream, Encoding.UTF8); + var text = reader.ReadToEnd(); + + using var wordDocument = WordprocessingDocument.Create(targetStream, WordprocessingDocumentType.Document); + wordDocument.AddMainDocumentPart(); + var mainPart = wordDocument.MainDocumentPart!; + + mainPart.Document = new Document(); + var body = new Body(); + + var lines = text.Split(new[] { '\r', '\n' }, StringSplitOptions.None); + foreach (var line in lines) + { + var paragraph = new Paragraph(); + var run = new Run(); + run.Append(new Text(line)); + paragraph.Append(run); + body.Append(paragraph); + } + + mainPart.Document.Append(body); + mainPart.Document.Save(); + }); + } + } +} diff --git a/FileConvertor/Core/Converters/TiffToJpgConverter.cs b/FileConvertor/Core/Converters/TiffToJpgConverter.cs new file mode 100644 index 0000000..4e4a1ad --- /dev/null +++ b/FileConvertor/Core/Converters/TiffToJpgConverter.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace FileConvertor.Core.Converters +{ + public class TiffToJpgConverter : BaseConverter + { + public override string SourceFormat => "tiff"; + public override string TargetFormat => "jpg"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + var decoder = new TiffBitmapDecoder(sourceStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); + var encoder = new JpegBitmapEncoder { QualityLevel = 90 }; + + encoder.Frames.Add(BitmapFrame.Create(decoder.Frames[0])); + encoder.Save(targetStream); + }); + } + } +} diff --git a/FileConvertor/Core/Converters/TiffToPngConverter.cs b/FileConvertor/Core/Converters/TiffToPngConverter.cs new file mode 100644 index 0000000..af74e82 --- /dev/null +++ b/FileConvertor/Core/Converters/TiffToPngConverter.cs @@ -0,0 +1,25 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using System.Windows.Media.Imaging; + +namespace FileConvertor.Core.Converters +{ + public class TiffToPngConverter : BaseConverter + { + public override string SourceFormat => "tiff"; + public override string TargetFormat => "png"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + var decoder = new TiffBitmapDecoder(sourceStream, BitmapCreateOptions.PreservePixelFormat, BitmapCacheOption.OnLoad); + var encoder = new PngBitmapEncoder(); + + encoder.Frames.Add(BitmapFrame.Create(decoder.Frames[0])); + encoder.Save(targetStream); + }); + } + } +} diff --git a/FileConvertor/Core/Converters/WebmToMp4Converter.cs b/FileConvertor/Core/Converters/WebmToMp4Converter.cs new file mode 100644 index 0000000..e119183 --- /dev/null +++ b/FileConvertor/Core/Converters/WebmToMp4Converter.cs @@ -0,0 +1,49 @@ +using System; +using System.IO; +using System.Linq; +using System.Threading.Tasks; +using Xabe.FFmpeg; + +namespace FileConvertor.Core.Converters +{ + public class WebmToMp4Converter : BaseConverter + { + public override string SourceFormat => "webm"; + public override string TargetFormat => "mp4"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + var tempInput = Path.GetTempFileName(); + var tempOutput = Path.GetTempFileName(); + + try + { + using (var fileStream = File.Create(tempInput)) + { + await sourceStream.CopyToAsync(fileStream); + } + + var mediaInfo = await FFmpeg.GetMediaInfo(tempInput); + var conversion = FFmpeg.Conversions.New(); + + if (mediaInfo.VideoStreams.Any()) + conversion.AddStream(mediaInfo.VideoStreams.First()); + + if (mediaInfo.AudioStreams.Any()) + conversion.AddStream(mediaInfo.AudioStreams.First()); + + await conversion + .SetOutput(tempOutput) + .Start(); + + using var outputFile = File.OpenRead(tempOutput); + await outputFile.CopyToAsync(targetStream); + } + finally + { + if (File.Exists(tempInput)) File.Delete(tempInput); + if (File.Exists(tempOutput)) File.Delete(tempOutput); + } + } + } +} diff --git a/FileConvertor/Core/Converters/WebpToPngConverter.cs b/FileConvertor/Core/Converters/WebpToPngConverter.cs new file mode 100644 index 0000000..2623e45 --- /dev/null +++ b/FileConvertor/Core/Converters/WebpToPngConverter.cs @@ -0,0 +1,23 @@ +using System; +using System.IO; +using System.Threading.Tasks; +using SixLabors.ImageSharp; +using SixLabors.ImageSharp.Formats.Png; + +namespace FileConvertor.Core.Converters +{ + public class WebpToPngConverter : BaseConverter + { + public override string SourceFormat => "webp"; + public override string TargetFormat => "png"; + + public override async Task ConvertAsync(Stream sourceStream, Stream targetStream) + { + await Task.Run(() => + { + using var image = Image.Load(sourceStream); + image.Save(targetStream, new PngEncoder()); + }); + } + } +} diff --git a/FileConvertor/Core/Helpers/FileTypeDetector.cs b/FileConvertor/Core/Helpers/FileTypeDetector.cs index a30ed0f..f2b7c9b 100644 --- a/FileConvertor/Core/Helpers/FileTypeDetector.cs +++ b/FileConvertor/Core/Helpers/FileTypeDetector.cs @@ -61,15 +61,23 @@ private Dictionary