Animated preview generation code now read states from a PreviewStates.json file, preview generated using Mono runtime will have separate .png files instead of 1 .gif, added support for drawing correct weather icon depending on weather condition in state
|
@ -9,7 +9,7 @@ namespace Resources
|
||||||
{
|
{
|
||||||
public class ImageLoader
|
public class ImageLoader
|
||||||
{
|
{
|
||||||
public static readonly int NumericPartLength = 3;
|
public static readonly int NumericPartLength = 4;
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
public static Bitmap LoadImageForNumber(string directory, long index)
|
public static Bitmap LoadImageForNumber(string directory, long index)
|
||||||
|
|
|
@ -35,12 +35,15 @@
|
||||||
<HintPath>..\packages\Bumpkit.1.0.2\lib\BumpKit.dll</HintPath>
|
<HintPath>..\packages\Bumpkit.1.0.2\lib\BumpKit.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NLog.4.4.12\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.5.6\lib\net40-client\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Configuration" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="System.Runtime.Serialization" />
|
<Reference Include="System.Runtime.Serialization" />
|
||||||
|
<Reference Include="System.ServiceModel" />
|
||||||
|
<Reference Include="System.Transactions" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data.DataSetExtensions" />
|
<Reference Include="System.Data.DataSetExtensions" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
|
|
@ -1,5 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Bumpkit" version="1.0.2" targetFramework="net40-client" />
|
<package id="Bumpkit" version="1.0.2" targetFramework="net40-client" />
|
||||||
<package id="NLog" version="4.4.12" targetFramework="net40-client" />
|
<package id="NLog" version="4.5.6" targetFramework="net40-client" />
|
||||||
</packages>
|
</packages>
|
|
@ -9,9 +9,9 @@ namespace WatchFace.Parser.Models.Elements
|
||||||
|
|
||||||
public override void Draw(Graphics drawer, Bitmap[] resources, WatchState state)
|
public override void Draw(Graphics drawer, Bitmap[] resources, WatchState state)
|
||||||
{
|
{
|
||||||
if (state.Air == AirCondition.Unknown) return;
|
if (state.AirQuality == AirCondition.Unknown) return;
|
||||||
|
|
||||||
var imageIndex = (int) state.Air;
|
var imageIndex = (int) state.AirQuality;
|
||||||
Draw(drawer, resources, imageIndex);
|
Draw(drawer, resources, imageIndex);
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
|
@ -19,11 +19,14 @@ namespace WatchFace.Parser.Models.Elements
|
||||||
var useAltCoordinates = CurrentAlt != null && state.CurrentTemperature == null;
|
var useAltCoordinates = CurrentAlt != null && state.CurrentTemperature == null;
|
||||||
var iconCoordinates = useAltCoordinates ? CurrentAlt : Current;
|
var iconCoordinates = useAltCoordinates ? CurrentAlt : Current;
|
||||||
|
|
||||||
|
if (state.CurrentWeather > WeatherCondition.VeryHeavyDownpour ||
|
||||||
|
state.CurrentWeather < WeatherCondition.Unknown) return;
|
||||||
|
|
||||||
if (iconCoordinates != null)
|
if (iconCoordinates != null)
|
||||||
drawer.DrawImage(LoadWeatherImage(state.CurrentWeather), iconCoordinates.X, iconCoordinates.Y);
|
drawer.DrawImage(LoadWeatherImage(state.CurrentWeather), iconCoordinates.X, iconCoordinates.Y);
|
||||||
|
|
||||||
if (CustomIcon != null)
|
if (CustomIcon != null)
|
||||||
drawer.DrawImage(resources[CustomIcon.ImageIndex + 1], CustomIcon.X, CustomIcon.Y);
|
drawer.DrawImage(resources[CustomIcon.ImageIndex + (int)state.CurrentWeather], CustomIcon.X, CustomIcon.Y);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Bitmap LoadWeatherImage(WeatherCondition weather)
|
private static Bitmap LoadWeatherImage(WeatherCondition weather)
|
||||||
|
|
|
@ -1,4 +1,6 @@
|
||||||
using System;
|
using System;
|
||||||
|
using Newtonsoft.Json;
|
||||||
|
using Newtonsoft.Json.Converters;
|
||||||
|
|
||||||
namespace WatchFace.Parser.Models
|
namespace WatchFace.Parser.Models
|
||||||
{
|
{
|
||||||
|
@ -12,15 +14,18 @@ namespace WatchFace.Parser.Models
|
||||||
public int Distance { get; set; } = 2367;
|
public int Distance { get; set; } = 2367;
|
||||||
public int? Pulse { get; set; } = 62;
|
public int? Pulse { get; set; } = 62;
|
||||||
|
|
||||||
|
|
||||||
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
|
public WeatherCondition CurrentWeather { get; set; } = WeatherCondition.PartlyCloudy;
|
||||||
public int? CurrentTemperature { get; set; } = -10;
|
public int? CurrentTemperature { get; set; } = -10;
|
||||||
public int? DayTemperature { get; set; } = -15;
|
public int? DayTemperature { get; set; } = -15;
|
||||||
public int? NightTemperature { get; set; } = -24;
|
public int? NightTemperature { get; set; } = -24;
|
||||||
public int? TomorrowDayTemperature { get; set; }
|
public int? TomorrowDayTemperature { get; set; }
|
||||||
public int? TomorrowNightTemperature { get; set; }
|
public int? TomorrowNightTemperature { get; set; }
|
||||||
public WeatherCondition CurrentWeather { get; set; } = WeatherCondition.Cloudy;
|
|
||||||
|
|
||||||
// https://en.wikipedia.org/wiki/Air_quality_index#Mainland_China
|
// https://en.wikipedia.org/wiki/Air_quality_index#Mainland_China
|
||||||
public AirCondition Air { get; set; } = AirCondition.Excellent;
|
[JsonConverter(typeof(StringEnumConverter))]
|
||||||
|
public AirCondition AirQuality { get; set; } = AirCondition.Excellent;
|
||||||
public int? AirQualityIndex { get; set; } = 15;
|
public int? AirQualityIndex { get; set; } = 15;
|
||||||
|
|
||||||
public int BatteryLevel { get; set; } = 67;
|
public int BatteryLevel { get; set; } = 67;
|
||||||
|
|
|
@ -2,7 +2,31 @@
|
||||||
{
|
{
|
||||||
public enum WeatherCondition
|
public enum WeatherCondition
|
||||||
{
|
{
|
||||||
Unknown = 279,
|
Unknown,
|
||||||
Cloudy = 247
|
PartlyCloudy,
|
||||||
|
CloudyAndRain,
|
||||||
|
CloudyAndSnow,
|
||||||
|
Sunny,
|
||||||
|
Cloudy,
|
||||||
|
LightRain,
|
||||||
|
LightSnow,
|
||||||
|
Rain,
|
||||||
|
Snow,
|
||||||
|
HeavySnow,
|
||||||
|
HeavyRain,
|
||||||
|
SandStorm,
|
||||||
|
SnowAndRain,
|
||||||
|
Fog,
|
||||||
|
Haze,
|
||||||
|
Storm,
|
||||||
|
VeryHeavySnow,
|
||||||
|
FloatingDust,
|
||||||
|
Downpour,
|
||||||
|
Hail,
|
||||||
|
HailStorm,
|
||||||
|
HeavyDownpour,
|
||||||
|
BlowingDust,
|
||||||
|
Tornado,
|
||||||
|
VeryHeavyDownpour
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -1,8 +1,5 @@
|
||||||
using System;
|
using System.Collections.Generic;
|
||||||
using System.Collections.Generic;
|
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.IO;
|
|
||||||
using BumpKit;
|
|
||||||
using WatchFace.Parser.Interfaces;
|
using WatchFace.Parser.Interfaces;
|
||||||
using WatchFace.Parser.Models;
|
using WatchFace.Parser.Models;
|
||||||
|
|
||||||
|
@ -10,63 +7,23 @@ namespace WatchFace.Parser
|
||||||
{
|
{
|
||||||
public class PreviewGenerator
|
public class PreviewGenerator
|
||||||
{
|
{
|
||||||
public static void CreateGif(List<Parameter> descriptor, Bitmap[] images, Stream outputStream)
|
public static IEnumerable<Image> CreateAnimation(List<Parameter> descriptor, Bitmap[] images,
|
||||||
|
IEnumerable<WatchState> states)
|
||||||
{
|
{
|
||||||
var previewWatchFace = new Models.Elements.WatchFace(descriptor);
|
var previewWatchFace = new Models.Elements.WatchFace(descriptor);
|
||||||
var watchState = new WatchState();
|
foreach (var watchState in states)
|
||||||
var time = watchState.Time;
|
|
||||||
|
|
||||||
using (var encoder = new GifEncoder(outputStream))
|
|
||||||
{
|
{
|
||||||
for (var i = 0; i < 10; i++)
|
using (var image = CreateFrame(previewWatchFace, images, watchState))
|
||||||
{
|
{
|
||||||
var num = i + 1;
|
yield return image;
|
||||||
watchState.BatteryLevel = 100 - (num * 10);
|
|
||||||
|
|
||||||
watchState.Pulse = 60 + num * 2;
|
|
||||||
watchState.Steps = num * 1000;
|
|
||||||
watchState.Calories = num * 75;
|
|
||||||
watchState.Distance = num * 700;
|
|
||||||
|
|
||||||
watchState.Bluetooth = num > 1 && num < 6;
|
|
||||||
watchState.Unlocked = num > 2 && num < 7;
|
|
||||||
watchState.Alarm = num > 3 && num < 8;
|
|
||||||
watchState.DoNotDisturb = num > 4 && num < 9;
|
|
||||||
|
|
||||||
watchState.DayTemperature += 2;
|
|
||||||
watchState.NightTemperature += 4;
|
|
||||||
|
|
||||||
if (num < 3)
|
|
||||||
{
|
|
||||||
watchState.Air = AirCondition.Unknown;
|
|
||||||
watchState.AirQualityIndex = null;
|
|
||||||
}
|
|
||||||
else
|
|
||||||
{
|
|
||||||
watchState.Air = (AirCondition) (num - 3);
|
|
||||||
watchState.AirQualityIndex = (num - 2) * 50 - 25;
|
|
||||||
}
|
|
||||||
|
|
||||||
if (num < 3)
|
|
||||||
watchState.CurrentTemperature = null;
|
|
||||||
else if (num == 3)
|
|
||||||
watchState.CurrentTemperature = -10;
|
|
||||||
else
|
|
||||||
watchState.CurrentTemperature += 6;
|
|
||||||
|
|
||||||
watchState.Time = new DateTime(time.Year, num, num * 2 + 5, i * 2, i * 6, i);
|
|
||||||
using (var image = CreateFrame(previewWatchFace, images, watchState))
|
|
||||||
{
|
|
||||||
encoder.AddFrame(image, frameDelay: TimeSpan.FromSeconds(1));
|
|
||||||
}
|
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
||||||
|
|
||||||
public static Image CreateImage(IEnumerable<Parameter> descriptor, Bitmap[] resources)
|
public static Image CreateImage(IEnumerable<Parameter> descriptor, Bitmap[] images, WatchState state)
|
||||||
{
|
{
|
||||||
var previewWatchFace = new Models.Elements.WatchFace(descriptor);
|
var previewWatchFace = new Models.Elements.WatchFace(descriptor);
|
||||||
return CreateFrame(previewWatchFace, resources, new WatchState());
|
return CreateFrame(previewWatchFace, images, state);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static Image CreateFrame(IDrawable watchFace, Bitmap[] resources, WatchState state)
|
private static Image CreateFrame(IDrawable watchFace, Bitmap[] resources, WatchState state)
|
||||||
|
|
|
@ -31,19 +31,19 @@
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="BumpKit, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Bumpkit.1.0.2\lib\BumpKit.dll</HintPath>
|
<HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
|
||||||
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
|
||||||
<HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
|
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NLog.4.4.12\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.5.6\lib\net40-client\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Configuration" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="System.Runtime.Serialization" />
|
<Reference Include="System.Runtime.Serialization" />
|
||||||
|
<Reference Include="System.ServiceModel" />
|
||||||
|
<Reference Include="System.Transactions" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="Microsoft.CSharp" />
|
<Reference Include="Microsoft.CSharp" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
|
@ -173,9 +173,34 @@
|
||||||
<None Include="packages.config" />
|
<None Include="packages.config" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<EmbeddedResource Include="WeatherIcons\247.png" />
|
<EmbeddedResource Include="WeatherIcons\1.png" />
|
||||||
<EmbeddedResource Include="WeatherIcons\279.png" />
|
<EmbeddedResource Include="WeatherIcons\0.png" />
|
||||||
|
</ItemGroup>
|
||||||
|
<ItemGroup>
|
||||||
|
<EmbeddedResource Include="WeatherIcons\10.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\11.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\12.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\13.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\14.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\15.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\16.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\17.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\18.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\19.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\2.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\20.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\21.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\22.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\23.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\24.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\25.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\3.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\4.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\5.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\6.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\7.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\8.png" />
|
||||||
|
<EmbeddedResource Include="WeatherIcons\9.png" />
|
||||||
</ItemGroup>
|
</ItemGroup>
|
||||||
<ItemGroup />
|
|
||||||
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
<Import Project="$(MSBuildToolsPath)\Microsoft.CSharp.targets" />
|
||||||
</Project>
|
</Project>
|
Before Width: | Height: | Size: 332 B After Width: | Height: | Size: 332 B |
Before Width: | Height: | Size: 352 B After Width: | Height: | Size: 352 B |
After Width: | Height: | Size: 334 B |
After Width: | Height: | Size: 325 B |
After Width: | Height: | Size: 288 B |
After Width: | Height: | Size: 334 B |
After Width: | Height: | Size: 236 B |
After Width: | Height: | Size: 302 B |
After Width: | Height: | Size: 365 B |
After Width: | Height: | Size: 340 B |
After Width: | Height: | Size: 229 B |
After Width: | Height: | Size: 319 B |
After Width: | Height: | Size: 372 B |
After Width: | Height: | Size: 335 B |
After Width: | Height: | Size: 367 B |
After Width: | Height: | Size: 316 B |
After Width: | Height: | Size: 270 B |
After Width: | Height: | Size: 278 B |
After Width: | Height: | Size: 305 B |
After Width: | Height: | Size: 374 B |
After Width: | Height: | Size: 326 B |
After Width: | Height: | Size: 297 B |
After Width: | Height: | Size: 314 B |
After Width: | Height: | Size: 316 B |
After Width: | Height: | Size: 324 B |
After Width: | Height: | Size: 319 B |
|
@ -1,6 +1,5 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Bumpkit" version="1.0.2" targetFramework="net40-client" />
|
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net40-client" />
|
||||||
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net40-client" />
|
<package id="NLog" version="4.5.6" targetFramework="net40-client" />
|
||||||
<package id="NLog" version="4.4.12" targetFramework="net40-client" />
|
|
||||||
</packages>
|
</packages>
|
|
@ -3,6 +3,8 @@ using System.Collections.Generic;
|
||||||
using System.Drawing;
|
using System.Drawing;
|
||||||
using System.Drawing.Imaging;
|
using System.Drawing.Imaging;
|
||||||
using System.IO;
|
using System.IO;
|
||||||
|
using System.Reflection;
|
||||||
|
using BumpKit;
|
||||||
using Newtonsoft.Json;
|
using Newtonsoft.Json;
|
||||||
using NLog;
|
using NLog;
|
||||||
using NLog.Config;
|
using NLog.Config;
|
||||||
|
@ -10,6 +12,7 @@ using NLog.Targets;
|
||||||
using Resources;
|
using Resources;
|
||||||
using Resources.Models;
|
using Resources.Models;
|
||||||
using WatchFace.Parser;
|
using WatchFace.Parser;
|
||||||
|
using WatchFace.Parser.Models;
|
||||||
using WatchFace.Parser.Utils;
|
using WatchFace.Parser.Utils;
|
||||||
using Reader = WatchFace.Parser.Reader;
|
using Reader = WatchFace.Parser.Reader;
|
||||||
using Writer = WatchFace.Parser.Writer;
|
using Writer = WatchFace.Parser.Writer;
|
||||||
|
@ -20,6 +23,7 @@ namespace WatchFace
|
||||||
{
|
{
|
||||||
private const string AppName = "WatchFace";
|
private const string AppName = "WatchFace";
|
||||||
|
|
||||||
|
private static readonly bool IsRunningOnMono = Type.GetType("Mono.Runtime") != null;
|
||||||
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
private static readonly Logger Logger = LogManager.GetCurrentClassLogger();
|
||||||
|
|
||||||
private static void Main(string[] args)
|
private static void Main(string[] args)
|
||||||
|
@ -107,7 +111,7 @@ namespace WatchFace
|
||||||
var imagesDirectory = Path.GetDirectoryName(inputFileName);
|
var imagesDirectory = Path.GetDirectoryName(inputFileName);
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
WriteWatchFace(outputFileName, imagesDirectory, watchFace);
|
WriteWatchFace(outputDirectory, outputFileName, imagesDirectory, watchFace);
|
||||||
}
|
}
|
||||||
catch (Exception)
|
catch (Exception)
|
||||||
{
|
{
|
||||||
|
@ -128,13 +132,8 @@ namespace WatchFace
|
||||||
var watchFace = ParseResources(reader);
|
var watchFace = ParseResources(reader);
|
||||||
if (watchFace == null) return;
|
if (watchFace == null) return;
|
||||||
|
|
||||||
Logger.Debug("Generating previews...");
|
|
||||||
var preview = PreviewGenerator.CreateImage(reader.Parameters, reader.Images.ToArray());
|
GeneratePreviews(reader.Parameters, reader.Images.ToArray(), outputDirectory, baseName);
|
||||||
preview.Save(Path.Combine(outputDirectory, $"{baseName}_preview.png"), ImageFormat.Png);
|
|
||||||
using (var gifOutput = File.OpenWrite(Path.Combine(outputDirectory, $"{baseName}_preview.gif")))
|
|
||||||
{
|
|
||||||
PreviewGenerator.CreateGif(reader.Parameters, reader.Images.ToArray(), gifOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.Debug("Exporting resources to '{0}'", outputDirectory);
|
Logger.Debug("Exporting resources to '{0}'", outputDirectory);
|
||||||
var reDescriptor = new FileDescriptor {Images = reader.Images};
|
var reDescriptor = new FileDescriptor {Images = reader.Images};
|
||||||
|
@ -192,7 +191,8 @@ namespace WatchFace
|
||||||
}
|
}
|
||||||
|
|
||||||
if (resDescriptor.ResourcesCount != null && resDescriptor.ResourcesCount.Value != images.Count)
|
if (resDescriptor.ResourcesCount != null && resDescriptor.ResourcesCount.Value != images.Count)
|
||||||
throw new ArgumentException($"The .res-file should contain {resDescriptor.ResourcesCount.Value} images but was loaded {images.Count} images.");
|
throw new ArgumentException(
|
||||||
|
$"The .res-file should contain {resDescriptor.ResourcesCount.Value} images but was loaded {images.Count} images.");
|
||||||
|
|
||||||
resDescriptor.Images = images;
|
resDescriptor.Images = images;
|
||||||
|
|
||||||
|
@ -218,7 +218,7 @@ namespace WatchFace
|
||||||
new Extractor(resDescriptor).Extract(outputDirectory);
|
new Extractor(resDescriptor).Extract(outputDirectory);
|
||||||
}
|
}
|
||||||
|
|
||||||
private static void WriteWatchFace(string outputFileName, string imagesDirectory, Parser.WatchFace watchFace)
|
private static void WriteWatchFace(string outputDirectory, string outputFileName, string imagesDirectory, Parser.WatchFace watchFace)
|
||||||
{
|
{
|
||||||
try
|
try
|
||||||
{
|
{
|
||||||
|
@ -229,13 +229,8 @@ namespace WatchFace
|
||||||
Logger.Trace("Building parameters for watch face...");
|
Logger.Trace("Building parameters for watch face...");
|
||||||
var descriptor = ParametersConverter.Build(watchFace);
|
var descriptor = ParametersConverter.Build(watchFace);
|
||||||
|
|
||||||
Logger.Debug("Generating preview...");
|
var baseFilename = Path.GetFileNameWithoutExtension(outputFileName);
|
||||||
var preview = PreviewGenerator.CreateImage(descriptor, imagesReader.Images.ToArray());
|
GeneratePreviews(descriptor, imagesReader.Images.ToArray(), outputDirectory, baseFilename);
|
||||||
preview.Save(Path.ChangeExtension(outputFileName, ".png"));
|
|
||||||
using (var gifOutput = File.OpenWrite(Path.ChangeExtension(outputFileName, ".gif")))
|
|
||||||
{
|
|
||||||
PreviewGenerator.CreateGif(descriptor, imagesReader.Images.ToArray(), gifOutput);
|
|
||||||
}
|
|
||||||
|
|
||||||
Logger.Debug("Writing watch face to '{0}'", outputFileName);
|
Logger.Debug("Writing watch face to '{0}'", outputFileName);
|
||||||
using (var fileStream = File.OpenWrite(outputFileName))
|
using (var fileStream = File.OpenWrite(outputFileName))
|
||||||
|
@ -400,5 +395,109 @@ namespace WatchFace
|
||||||
|
|
||||||
LogManager.Configuration = config;
|
LogManager.Configuration = config;
|
||||||
}
|
}
|
||||||
|
|
||||||
|
private static void GeneratePreviews(List<Parameter> parameters, Bitmap[] images, string outputDirectory, string baseName)
|
||||||
|
{
|
||||||
|
Logger.Debug("Generating previews...");
|
||||||
|
|
||||||
|
var states = GetPreviewStates();
|
||||||
|
var staticPreview = PreviewGenerator.CreateImage(parameters, images, new WatchState());
|
||||||
|
staticPreview.Save(Path.Combine(outputDirectory, $"{baseName}_static.png"), ImageFormat.Png);
|
||||||
|
|
||||||
|
var previewImages = PreviewGenerator.CreateAnimation(parameters, images, states);
|
||||||
|
|
||||||
|
if (IsRunningOnMono)
|
||||||
|
{
|
||||||
|
var i = 0;
|
||||||
|
foreach (var previewImage in previewImages)
|
||||||
|
{
|
||||||
|
previewImage.Save(Path.Combine(outputDirectory, $"{baseName}_animated_{i}.png"), ImageFormat.Png);
|
||||||
|
i++;
|
||||||
|
}
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
using (var gifOutput = File.OpenWrite(Path.Combine(outputDirectory, $"{baseName}_animated.gif")))
|
||||||
|
using (var encoder = new GifEncoder(gifOutput))
|
||||||
|
{
|
||||||
|
foreach (var previewImage in previewImages)
|
||||||
|
encoder.AddFrame(previewImage, frameDelay: TimeSpan.FromSeconds(1));
|
||||||
|
}
|
||||||
|
}
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<WatchState> GetPreviewStates()
|
||||||
|
{
|
||||||
|
var appPath = Path.GetDirectoryName(Assembly.GetExecutingAssembly().Location);
|
||||||
|
var previewStatesPath = Path.Combine(appPath, "PreviewStates.json");
|
||||||
|
|
||||||
|
if (File.Exists(previewStatesPath))
|
||||||
|
using (var stream = File.OpenRead(previewStatesPath))
|
||||||
|
using (var reader = new StreamReader(stream))
|
||||||
|
{
|
||||||
|
var json = reader.ReadToEnd();
|
||||||
|
return JsonConvert.DeserializeObject<List<WatchState>>(json);
|
||||||
|
}
|
||||||
|
|
||||||
|
var previewStates = GenerateSampleStates();
|
||||||
|
using (var stream = File.OpenWrite(previewStatesPath))
|
||||||
|
using (var writer = new StreamWriter(stream))
|
||||||
|
{
|
||||||
|
var json = JsonConvert.SerializeObject(previewStates, Formatting.Indented);
|
||||||
|
writer.Write(json);
|
||||||
|
writer.Flush();
|
||||||
|
}
|
||||||
|
|
||||||
|
return previewStates;
|
||||||
|
}
|
||||||
|
|
||||||
|
private static IEnumerable<WatchState> GenerateSampleStates()
|
||||||
|
{
|
||||||
|
var time = DateTime.Now;
|
||||||
|
var states = new List<WatchState>();
|
||||||
|
|
||||||
|
for (var i = 0; i < 10; i++)
|
||||||
|
{
|
||||||
|
var num = i + 1;
|
||||||
|
var watchState = new WatchState
|
||||||
|
{
|
||||||
|
BatteryLevel = 100 - i * 10,
|
||||||
|
Pulse = 60 + num * 2,
|
||||||
|
Steps = num * 1000,
|
||||||
|
Calories = num * 75,
|
||||||
|
Distance = num * 700,
|
||||||
|
Bluetooth = num > 1 && num < 6,
|
||||||
|
Unlocked = num > 2 && num < 7,
|
||||||
|
Alarm = num > 3 && num < 8,
|
||||||
|
DoNotDisturb = num > 4 && num < 9,
|
||||||
|
|
||||||
|
DayTemperature = -15 + 2 * i,
|
||||||
|
NightTemperature = -24 + i * 4,
|
||||||
|
};
|
||||||
|
|
||||||
|
if (num < 3)
|
||||||
|
{
|
||||||
|
watchState.AirQuality = AirCondition.Unknown;
|
||||||
|
watchState.AirQualityIndex = null;
|
||||||
|
|
||||||
|
watchState.CurrentWeather = WeatherCondition.Unknown;
|
||||||
|
watchState.CurrentTemperature = null;
|
||||||
|
}
|
||||||
|
else
|
||||||
|
{
|
||||||
|
var index = num - 2;
|
||||||
|
watchState.AirQuality = (AirCondition) index;
|
||||||
|
watchState.CurrentWeather = (WeatherCondition) index;
|
||||||
|
|
||||||
|
watchState.AirQualityIndex = index * 50 - 25;
|
||||||
|
watchState.CurrentTemperature = -10 + i * 6;
|
||||||
|
}
|
||||||
|
|
||||||
|
watchState.Time = new DateTime(time.Year, num, num * 2 + 5, i * 2, i * 6, i);
|
||||||
|
states.Add(watchState);
|
||||||
|
}
|
||||||
|
|
||||||
|
return states;
|
||||||
|
}
|
||||||
}
|
}
|
||||||
}
|
}
|
|
@ -35,16 +35,24 @@
|
||||||
<WarningLevel>4</WarningLevel>
|
<WarningLevel>4</WarningLevel>
|
||||||
</PropertyGroup>
|
</PropertyGroup>
|
||||||
<ItemGroup>
|
<ItemGroup>
|
||||||
<Reference Include="Newtonsoft.Json, Version=10.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
<Reference Include="BumpKit, Version=1.0.0.0, Culture=neutral, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\Newtonsoft.Json.10.0.3\lib\net40\Newtonsoft.Json.dll</HintPath>
|
<HintPath>..\packages\Bumpkit.1.0.2\lib\BumpKit.dll</HintPath>
|
||||||
|
</Reference>
|
||||||
|
<Reference Include="Microsoft.CSharp" />
|
||||||
|
<Reference Include="Newtonsoft.Json, Version=11.0.0.0, Culture=neutral, PublicKeyToken=30ad4fe6b2a6aeed, processorArchitecture=MSIL">
|
||||||
|
<HintPath>..\packages\Newtonsoft.Json.11.0.2\lib\net40\Newtonsoft.Json.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
<Reference Include="NLog, Version=4.0.0.0, Culture=neutral, PublicKeyToken=5120e14c03d0593c, processorArchitecture=MSIL">
|
||||||
<HintPath>..\packages\NLog.4.4.12\lib\net40\NLog.dll</HintPath>
|
<HintPath>..\packages\NLog.4.5.6\lib\net40-client\NLog.dll</HintPath>
|
||||||
</Reference>
|
</Reference>
|
||||||
<Reference Include="System" />
|
<Reference Include="System" />
|
||||||
|
<Reference Include="System.Configuration" />
|
||||||
<Reference Include="System.Core" />
|
<Reference Include="System.Core" />
|
||||||
<Reference Include="System.Drawing" />
|
<Reference Include="System.Drawing" />
|
||||||
<Reference Include="System.Numerics" />
|
<Reference Include="System.Numerics" />
|
||||||
|
<Reference Include="System.Runtime.Serialization" />
|
||||||
|
<Reference Include="System.ServiceModel" />
|
||||||
|
<Reference Include="System.Transactions" />
|
||||||
<Reference Include="System.Xml.Linq" />
|
<Reference Include="System.Xml.Linq" />
|
||||||
<Reference Include="System.Data" />
|
<Reference Include="System.Data" />
|
||||||
<Reference Include="System.Xml" />
|
<Reference Include="System.Xml" />
|
||||||
|
|
|
@ -1,6 +1,6 @@
|
||||||
<?xml version="1.0" encoding="utf-8"?>
|
<?xml version="1.0" encoding="utf-8"?>
|
||||||
|
|
||||||
<packages>
|
<packages>
|
||||||
<package id="Newtonsoft.Json" version="10.0.3" targetFramework="net40-client" />
|
<package id="Bumpkit" version="1.0.2" targetFramework="net40-client" />
|
||||||
<package id="NLog" version="4.4.12" targetFramework="net40-client" />
|
<package id="Newtonsoft.Json" version="11.0.2" targetFramework="net40-client" />
|
||||||
|
<package id="NLog" version="4.5.6" targetFramework="net40-client" />
|
||||||
</packages>
|
</packages>
|