From c51b03c3460d526c970b1d17ea9473fad6830155 Mon Sep 17 00:00:00 2001 From: Emiliano Magliocca Date: Tue, 15 Jun 2021 16:54:30 +0200 Subject: [PATCH] Add save as text for Ascii Art --- Yugen.Mosaic.Uwp/Enums/FileFormat.cs | 5 ++- Yugen.Mosaic.Uwp/Interfaces/IMosaicService.cs | 2 + .../ISearchAndReplaceAsciiArtService.cs | 2 + Yugen.Mosaic.Uwp/Services/MosaicService.cs | 7 +++- .../SearchAndReplaceAsciiArtService.cs | 12 +++--- Yugen.Mosaic.Uwp/Strings/en-US/Resources.resw | 10 ++++- Yugen.Mosaic.Uwp/ViewModels/MainViewModel.cs | 42 ++++++++++++++++++- Yugen.Mosaic.Uwp/Views/MainPage.xaml | 18 +++++++- 8 files changed, 87 insertions(+), 11 deletions(-) diff --git a/Yugen.Mosaic.Uwp/Enums/FileFormat.cs b/Yugen.Mosaic.Uwp/Enums/FileFormat.cs index b9b8b2a..c8287cb 100644 --- a/Yugen.Mosaic.Uwp/Enums/FileFormat.cs +++ b/Yugen.Mosaic.Uwp/Enums/FileFormat.cs @@ -20,6 +20,9 @@ public enum FileFormat Tiff, [Description(".gif")] - Gif + Gif, + + [Description(".txt")] + Txt } } \ No newline at end of file diff --git a/Yugen.Mosaic.Uwp/Interfaces/IMosaicService.cs b/Yugen.Mosaic.Uwp/Interfaces/IMosaicService.cs index e78a767..ccee20a 100644 --- a/Yugen.Mosaic.Uwp/Interfaces/IMosaicService.cs +++ b/Yugen.Mosaic.Uwp/Interfaces/IMosaicService.cs @@ -10,6 +10,8 @@ namespace Yugen.Mosaic.Uwp.Interfaces { public interface IMosaicService { + string GetAsciiText { get; } + Task AddMasterImage(StorageFile file); void AddTileImage(string name, StorageFile file); diff --git a/Yugen.Mosaic.Uwp/Interfaces/ISearchAndReplaceAsciiArtService.cs b/Yugen.Mosaic.Uwp/Interfaces/ISearchAndReplaceAsciiArtService.cs index 4abb4e6..1f47885 100644 --- a/Yugen.Mosaic.Uwp/Interfaces/ISearchAndReplaceAsciiArtService.cs +++ b/Yugen.Mosaic.Uwp/Interfaces/ISearchAndReplaceAsciiArtService.cs @@ -5,6 +5,8 @@ namespace Yugen.Mosaic.Uwp.Interfaces { public interface ISearchAndReplaceAsciiArtService { + string Text { get; } + Image SearchAndReplace(Image masterImage, int ratio = 5); } } \ No newline at end of file diff --git a/Yugen.Mosaic.Uwp/Services/MosaicService.cs b/Yugen.Mosaic.Uwp/Services/MosaicService.cs index cdd7d8e..be4660b 100644 --- a/Yugen.Mosaic.Uwp/Services/MosaicService.cs +++ b/Yugen.Mosaic.Uwp/Services/MosaicService.cs @@ -33,8 +33,9 @@ public class MosaicService : IMosaicService private ISearchAndReplaceService _searchAndReplaceService; private readonly ISearchAndReplaceServiceFactory _searchAndReplaceServiceFactory; - - public MosaicService(IProgressService progressService, ISearchAndReplaceAsciiArtService searchAndReplaceAsciiArtService, + public MosaicService( + IProgressService progressService, + ISearchAndReplaceAsciiArtService searchAndReplaceAsciiArtService, ISearchAndReplaceServiceFactory searchAndReplaceServiceFactory) { _progressService = progressService; @@ -44,6 +45,8 @@ public MosaicService(IProgressService progressService, ISearchAndReplaceAsciiArt StorageApplicationPermissions.FutureAccessList.Clear(); } + public string GetAsciiText => _searchAndReplaceAsciiArtService.Text; + public async Task AddMasterImage(StorageFile storageFile) { using (var inputStream = await storageFile.OpenReadAsync()) diff --git a/Yugen.Mosaic.Uwp/Services/SearchAndReplaceAsciiArtService.cs b/Yugen.Mosaic.Uwp/Services/SearchAndReplaceAsciiArtService.cs index e60961e..21d71f4 100644 --- a/Yugen.Mosaic.Uwp/Services/SearchAndReplaceAsciiArtService.cs +++ b/Yugen.Mosaic.Uwp/Services/SearchAndReplaceAsciiArtService.cs @@ -23,10 +23,12 @@ public SearchAndReplaceAsciiArtService(IProgressService progressService) _progressService = progressService; } + public string Text { get; private set; } + public Image SearchAndReplace(Image masterImage, int ratio = 5) { - var text = GenerateText(masterImage, ratio); - + Text = GenerateText(masterImage, ratio); + CanvasDevice device = CanvasDevice.GetSharedDevice(); CanvasTextFormat textFormat = new CanvasTextFormat() { @@ -36,16 +38,16 @@ public Image SearchAndReplace(Image masterImage, int ratio = 5) VerticalAlignment = CanvasVerticalAlignment.Top, WordWrapping = CanvasWordWrapping.NoWrap }; - var textLayout = new CanvasTextLayout(device, text, textFormat, 100, 100); + var textLayout = new CanvasTextLayout(device, Text, textFormat, 100, 100); - CanvasRenderTarget renderTarget = new CanvasRenderTarget(device, (float)textLayout.LayoutBounds.Width, + CanvasRenderTarget renderTarget = new CanvasRenderTarget(device, (float)textLayout.LayoutBounds.Width, (float)textLayout.LayoutBounds.Height, 96); using (var ds = renderTarget.CreateDrawingSession()) { ds.Clear(Colors.White); ds.DrawTextLayout(textLayout, 0, 0, Colors.Black); - } + } return Generate(renderTarget).Result; } diff --git a/Yugen.Mosaic.Uwp/Strings/en-US/Resources.resw b/Yugen.Mosaic.Uwp/Strings/en-US/Resources.resw index 74c6069..b21bce1 100644 --- a/Yugen.Mosaic.Uwp/Strings/en-US/Resources.resw +++ b/Yugen.Mosaic.Uwp/Strings/en-US/Resources.resw @@ -171,6 +171,9 @@ Reset + + Save As Text + Save @@ -294,7 +297,12 @@ What's New - - We added a new mosaic type option "Ascii Art" for text based visual art. + v1.4 +- We added the option to save "Ascii Art" result as text file +- We squashed some bugs and made some performance improvements + +v1.3 +- We added a new mosaic type option "Ascii Art" for text based visual art. This graphic design technique will recreate your pictures with a set of printable characters pieced together. - We squashed some bugs and made some performance improvements diff --git a/Yugen.Mosaic.Uwp/ViewModels/MainViewModel.cs b/Yugen.Mosaic.Uwp/ViewModels/MainViewModel.cs index 31a069c..951ea2e 100644 --- a/Yugen.Mosaic.Uwp/ViewModels/MainViewModel.cs +++ b/Yugen.Mosaic.Uwp/ViewModels/MainViewModel.cs @@ -55,6 +55,7 @@ public class MainViewModel : ViewModelBase private int _tileHeight = 25; private int _tileWidth = 25; private int _progress = 0; + private bool _isSaveAsTextButtonVisible; public MainViewModel(IMosaicService mosaicService, IProgressService progressService) { @@ -70,6 +71,7 @@ public MainViewModel(IMosaicService mosaicService, IProgressService progressServ ClickTileCommand = new AsyncRelayCommand(ClickTileCommandBehavior); GenerateCommand = new AsyncRelayCommand(GenerateCommandBehavior); SaveCommand = new AsyncRelayCommand(SaveCommandBehavior); + SaveAsTextCommand = new AsyncRelayCommand(SaveAsTextCommandBehavior); ResetCommand = new RelayCommand(ResetCommandBehavior); HelpCommand = new RelayCommand(HelpCommandBehavior); WhatsNewCommand = new AsyncRelayCommand(WhatsNewCommandBehavior); @@ -151,7 +153,19 @@ public int OutputWidth public MosaicType SelectedMosaicType { get => _selectedMosaicType; - set => SetProperty(ref _selectedMosaicType, value); + set + { + if (SetProperty(ref _selectedMosaicType, value)) + { + IsSaveAsTextButtonVisible = _selectedMosaicType.MosaicTypeEnum == MosaicTypeEnum.AsciiArt; + } + } + } + + public bool IsSaveAsTextButtonVisible + { + get => _isSaveAsTextButtonVisible; + set => SetProperty(ref _isSaveAsTextButtonVisible, value); } public string TeachingTipSubTitle @@ -212,6 +226,8 @@ public int Progress public ICommand SaveCommand { get; } + public ICommand SaveAsTextCommand { get; } + public ICommand ResetCommand { get; } public ICommand HelpCommand { get; } @@ -481,6 +497,30 @@ private async Task SaveCommandBehavior() } } + StopProgressRing(); + } + + private async Task SaveAsTextCommandBehavior() + { + StartProgressRing(false); + + var fileTypes = new Dictionary>() + { + {FileFormat.Txt.ToString(), new List() {FileFormat.Txt.GetStringRepresentation()}} + }; + + StorageFile file = await FilePickerHelper.SaveFile("Mosaic", fileTypes, + Windows.Storage.Pickers.PickerLocationId.PicturesLibrary); + + var text = _mosaicService.GetAsciiText; + + if (file == null || _outputImage == null || string.IsNullOrEmpty(text)) + { + return; + } + + await FileIO.WriteTextAsync(file, text); + StopProgressRing(); } diff --git a/Yugen.Mosaic.Uwp/Views/MainPage.xaml b/Yugen.Mosaic.Uwp/Views/MainPage.xaml index 0e41947..8c281ba 100644 --- a/Yugen.Mosaic.Uwp/Views/MainPage.xaml +++ b/Yugen.Mosaic.Uwp/Views/MainPage.xaml @@ -87,7 +87,7 @@ + Visibility="{x:Bind ViewModel.IsAddMasterUIVisible, Mode=OneWay}"> + + + + + +