Files

344 lines
10 KiB
C#
Raw Permalink Normal View History

2019-09-19 21:38:07 +10:00
using MVVM;
2020-01-02 15:47:29 +11:00
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
2019-09-19 21:38:07 +10:00
using System;
using System.Collections.Generic;
using System.IO;
2019-09-19 21:38:07 +10:00
using System.Linq;
using System.Runtime.InteropServices.WindowsRuntime;
2019-09-19 21:38:07 +10:00
using System.Text;
using System.Threading.Tasks;
using UWP_Visual_Asset_Generator.Data;
using Windows.Foundation;
using Windows.Graphics.Imaging;
using Windows.Storage;
using Windows.Storage.Streams;
using Windows.UI;
using Windows.UI.Xaml.Media.Imaging;
2019-09-19 21:38:07 +10:00
namespace UWP_Visual_Asset_Generator.ViewModels
{
public class AssetViewModel : ValleyBaseViewModel
{
private AssetTemplate _template;
private bool _savedSuccessfully = false;
private WriteableBitmap _logo;
private BitmapImage _readOnlyLogoForDisplay;
2020-07-21 08:26:53 +10:00
Image<Rgba32> newLogo = null;
private int _topPadding = 0;
private int _bottomPadding = 0;
private bool _selectedForExport = true;
public MainViewModel mainViewModel { get; set; }
2019-09-19 21:38:07 +10:00
public AssetViewModel(AssetTemplate template)
2019-09-19 21:38:07 +10:00
{
_template = template;
ResetPadding();
mainViewModel = App.mainViewModel;
_savedSuccessfully = false;
SetupInitialLogo();
}
public bool SelectedForExport
{
get
{
return _selectedForExport;
}
set
{
if (_selectedForExport != value)
{
_selectedForExport = value;
NotifyPropertyChanged("SelectedForExport");
}
}
}
public WriteableBitmap Logo
{
get
{
return _logo;
}
set
{
if (_logo != value)
{
_logo = value;
NotifyPropertyChanged("Logo");
_readOnlyLogoForDisplay = null;
NotifyPropertyChanged("ReadOnlyLogoForDisplay");
}
}
2019-09-19 21:38:07 +10:00
}
public BitmapImage ReadOnlyLogoForDisplay
{
get
{
if (_readOnlyLogoForDisplay == null &&
Logo != null)
{
UpdateReadOnlyDisplayImage();
}
return _readOnlyLogoForDisplay;
}
}
private async Task UpdateReadOnlyDisplayImage()
{
_readOnlyLogoForDisplay = new BitmapImage();
InMemoryRandomAccessStream randstream = new InMemoryRandomAccessStream();
await Logo.ToStream(randstream, BitmapEncoder.PngEncoderId);
_readOnlyLogoForDisplay.SetSource(randstream);
NotifyPropertyChanged("ReadOnlyLogoForDisplay");
}
public string FileName
2019-09-19 21:38:07 +10:00
{
get
{
return _template.FileName;
2019-09-19 21:38:07 +10:00
}
}
public bool SavedSuccessfully
{
get
{
return _savedSuccessfully;
}
set
{
_savedSuccessfully = value;
NotifyPropertyChanged("SavedSuccessfully");
}
}
public int ImageHeight
{
get
2019-09-19 21:38:07 +10:00
{
return _template.ImageHeight;
}
}
public int ImageWidth
{
get
{
return _template.ImageWidth;
2019-09-19 21:38:07 +10:00
}
}
public int TopPadding
{
get
{
return _topPadding;
}
set
{
if (_topPadding != value)
{
_topPadding = value;
NotifyPropertyChanged("TopPadding");
ApplyLogo();
}
}
}
public int BottomPadding
{
get
{
return _bottomPadding;
}
set
{
if (_bottomPadding != value)
{
_bottomPadding = value;
NotifyPropertyChanged("BottomPadding");
ApplyLogo();
}
}
}
private void SetupInitialLogo()
{
_logo = new WriteableBitmap(ImageWidth, ImageHeight);
EraseImage();
}
private void EraseImage()
{
Logo.Clear();
SavedSuccessfully = false;
}
2020-01-02 15:47:29 +11:00
public async Task<bool> ApplyLogo()
{
2020-01-02 15:47:29 +11:00
var result = false;
SetupInitialLogo();
if (mainViewModel != null &&
mainViewModel.originalWriteableBitmap != null &&
SelectedForExport)
{
2020-01-02 15:47:29 +11:00
try
{
int newLogoInsertHeight = ImageHeight - TopPadding - BottomPadding;
var config = new Configuration();
2019-09-21 21:43:45 +10:00
var backgroundPixel = new Rgba32();
if (mainViewModel.UseTransparentBackground)
{
backgroundPixel = SixLabors.ImageSharp.Color.Transparent;
}
else
{
backgroundPixel.R = mainViewModel.BackgroundColour.R;
backgroundPixel.G = mainViewModel.BackgroundColour.G;
backgroundPixel.B = mainViewModel.BackgroundColour.B;
backgroundPixel.A = mainViewModel.BackgroundColour.A;
}
2020-07-21 08:26:53 +10:00
newLogo = new Image<Rgba32>(config, ImageWidth, ImageHeight, backgroundPixel);
2020-01-02 15:47:29 +11:00
var options = new ResizeOptions()
{
Mode = ResizeMode.Max,
Position = AnchorPositionMode.Center,
2020-07-21 08:26:53 +10:00
Size = new SixLabors.ImageSharp.Size(ImageWidth - TwentyPercentOf(ImageWidth), newLogoInsertHeight),
Sampler = mainViewModel.SelectedResampler.Value
};
2020-01-02 15:47:29 +11:00
var inStream = await mainViewModel.OriginalLogoFile.OpenReadAsync();
var resizedOriginal = Image<Rgba32>.Load(inStream.AsStreamForRead());
//resize the image to fit the GIF frame bounds
resizedOriginal.Mutate(r => r.Resize(options));
//Get the top left point within the logo bounds
var left = HalfOf(ImageWidth) - HalfOf(resizedOriginal.Width);
var top = HalfOf(ImageHeight) - HalfOf(resizedOriginal.Height);
newLogo.Mutate(w => w.DrawImage(
resizedOriginal,
new SixLabors.ImageSharp.Point(left, top),
mainViewModel.SelectedBlendingMode.Value,
mainViewModel.SelectedAlphaMode.Value,
1));
2020-01-02 15:47:29 +11:00
InMemoryRandomAccessStream myStream = new InMemoryRandomAccessStream();
SixLabors.ImageSharp.Formats.Png.PngEncoder encoder = new SixLabors.ImageSharp.Formats.Png.PngEncoder();
encoder.CompressionLevel = App.mainViewModel.SelectedPNGCompression.Value;
newLogo.SaveAsPng(myStream.AsStream(), encoder);
2020-01-02 15:47:29 +11:00
myStream.Seek(0);
Logo = await BitmapFactory.FromStream(myStream);
NotifyPropertyChanged("Logo");
result = true;
}
catch (Exception ex)
{
}
SavedSuccessfully = false;
}
2020-01-02 15:47:29 +11:00
return result;
}
public int HalfOf(int halveMe)
{
double result = (double)halveMe / (double)2;
return Convert.ToInt32(result);
}
private int TwentyPercentOf(int twentyPercentOfMe)
{
double result = (double)twentyPercentOfMe / (double)5;
return Convert.ToInt32(result);
}
public void ResetPadding()
{
if (_template.PaddingIsRecommended)
{
_topPadding = HalfOf(HalfOf(_template.ImageHeight));
_bottomPadding = _topPadding;
}
else
{
_topPadding = 0;
_bottomPadding = 0;
}
NotifyPropertyChanged("TopPadding");
NotifyPropertyChanged("BottompPadding");
ApplyLogo();
}
2020-07-21 08:26:53 +10:00
public async Task ZeroPadding()
{
_topPadding = 0;
_bottomPadding = 0;
NotifyPropertyChanged("TopPadding");
NotifyPropertyChanged("BottompPadding");
2020-07-21 08:26:53 +10:00
await ApplyLogo();
}
public async Task<bool> SaveAssetToFileAsync()
{
var result = false;
2020-07-21 08:26:53 +10:00
if (newLogo != null)
{
2020-07-21 08:26:53 +10:00
if (SelectedForExport)
{
Thinking = true;
ThinkingText = "Saving";
await Task.Delay(App.ThinkingTinyPauseInMs);
2020-07-21 08:26:53 +10:00
try
{
2020-07-21 08:26:53 +10:00
if (mainViewModel.OutputFolder != null)
{
var outFile = await mainViewModel.OutputFolder.CreateFileAsync(FileName, Windows.Storage.CreationCollisionOption.ReplaceExisting);
using (IRandomAccessStream stream = await outFile.OpenAsync(FileAccessMode.ReadWrite))
{
newLogo.SaveAsPng(stream.AsStreamForWrite(), new SixLabors.ImageSharp.Formats.Png.PngEncoder());
}
result = true;
SavedSuccessfully = true;
ThinkingText = "Saved";
await Task.Delay(App.ThinkingTinyPauseInMs);
}
}
catch (Exception)
{
result = false;
}
}
}
Thinking = false;
ThinkingText = string.Empty;
return result;
}
2019-09-19 21:38:07 +10:00
}
}