Anime Matrix Editor

This commit is contained in:
Serge
2023-09-05 21:38:58 +02:00
parent fce9cddd02
commit b93499c20d
18 changed files with 784 additions and 108 deletions

View File

@@ -2,7 +2,9 @@
using NAudio.Wave;
using Starlight.AnimeMatrix;
using System.Diagnostics;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.IO;
using System.Timers;
namespace GHelper.AnimeMatrix
@@ -14,30 +16,32 @@ namespace GHelper.AnimeMatrix
SettingsForm settings;
System.Timers.Timer matrixTimer = default!;
AnimeMatrixDevice? mat;
public AnimeMatrixDevice? device;
double[]? AudioValues;
WasapiCapture? AudioDevice;
public bool IsValid => mat != null;
public bool IsValid => device != null;
private long lastPresent;
private List<double> maxes = new List<double>();
private MemoryStream ms = new MemoryStream();
public AniMatrixControl(SettingsForm settingsForm)
{
settings = settingsForm;
try
{
mat = new AnimeMatrixDevice();
Task.Run(mat.WakeUp);
device = new AnimeMatrixDevice();
Task.Run(device.WakeUp);
matrixTimer = new System.Timers.Timer(100);
matrixTimer.Elapsed += MatrixTimer_Elapsed;
}
catch
{
mat = null;
device = null;
}
}
@@ -67,24 +71,26 @@ namespace GHelper.AnimeMatrix
try
{
mat.SetProvider();
} catch (Exception ex) {
device.SetProvider();
}
catch (Exception ex)
{
Logger.WriteLine(ex.Message);
return;
}
if (wakeUp && AppConfig.ContainsModel("401")) mat.WakeUp();
if (wakeUp && AppConfig.ContainsModel("401")) device.WakeUp();
if (brightness == 0 || (auto && SystemInformation.PowerStatus.PowerLineStatus != PowerLineStatus.Online))
{
mat.SetDisplayState(false);
mat.SetDisplayState(false); // some devices are dumb
device.SetDisplayState(false);
device.SetDisplayState(false); // some devices are dumb
Logger.WriteLine("Matrix Off");
}
else
{
mat.SetDisplayState(true);
mat.SetBrightness((BrightnessMode)brightness);
device.SetDisplayState(true);
device.SetBrightness((BrightnessMode)brightness);
switch (running)
{
@@ -98,7 +104,7 @@ namespace GHelper.AnimeMatrix
SetMatrixAudio();
break;
default:
mat.SetBuiltInAnimation(true, animation);
device.SetBuiltInAnimation(true, animation);
Logger.WriteLine("Matrix builtin " + animation.AsByte);
break;
@@ -127,10 +133,10 @@ namespace GHelper.AnimeMatrix
switch (AppConfig.Get("matrix_running"))
{
case 2:
mat.PresentNextFrame();
device.PresentNextFrame();
break;
case 3:
mat.PresentClock();
device.PresentClock();
break;
}
@@ -139,7 +145,7 @@ namespace GHelper.AnimeMatrix
public void SetMatrixClock()
{
mat.SetBuiltInAnimation(false);
device.SetBuiltInAnimation(false);
StartMatrixTimer(1000);
Logger.WriteLine("Matrix Clock");
}
@@ -169,7 +175,7 @@ namespace GHelper.AnimeMatrix
{
if (!IsValid) return;
mat.SetBuiltInAnimation(false);
device.SetBuiltInAnimation(false);
StopMatrixTimer();
StopMatrixAudio();
@@ -238,8 +244,8 @@ namespace GHelper.AnimeMatrix
for (int x = 0; x < 2 - (y % 2); x++)
{
//color = (byte)(Math.Min(1,(h - y - 2)*2) * 255);
mat.SetLedPlanar(x + dx, dy + y, (byte)(h * 255 / 30));
mat.SetLedPlanar(x + dx, dy - y, 255);
device.SetLedPlanar(x + dx, dy + y, (byte)(h * 255 / 30));
device.SetLedPlanar(x + dx, dy - y, 255);
}
}
@@ -249,7 +255,7 @@ namespace GHelper.AnimeMatrix
if (Math.Abs(DateTimeOffset.Now.ToUnixTimeMilliseconds() - lastPresent) < 70) return;
lastPresent = DateTimeOffset.Now.ToUnixTimeMilliseconds();
mat.Clear();
device.Clear();
int size = 20;
double[] bars = new double[size];
@@ -267,7 +273,7 @@ namespace GHelper.AnimeMatrix
for (int i = 0; i < size; i++) DrawBar(20 - i, bars[i] * 20 / maxAverage);
mat.Present();
device.Present();
}
@@ -302,22 +308,27 @@ namespace GHelper.AnimeMatrix
}
public void SetMatrixPicture(string fileName)
public void SetMatrixPicture(string fileName, bool visualise = true)
{
if (!IsValid) return;
StopMatrixTimer();
Image image;
try
{
using (var fs = new FileStream(fileName, FileMode.Open))
{
var ms = new MemoryStream();
ms.SetLength(0);
fs.CopyTo(ms);
ms.Position = 0;
image = Image.FromStream(ms);
using (Image image = Image.FromStream(ms))
{
ProcessPicture(image);
Logger.WriteLine("Matrix " + fileName);
if (visualise) settings.VisualiseMatrix(image);
}
}
}
catch
@@ -326,30 +337,47 @@ namespace GHelper.AnimeMatrix
return;
}
mat.SetBuiltInAnimation(false);
mat.ClearFrames();
}
protected void ProcessPicture(Image image)
{
device.SetBuiltInAnimation(false);
device.ClearFrames();
int matrixX = AppConfig.Get("matrix_x", 0);
int matrixY = AppConfig.Get("matrix_y", 0);
int matrixZoom = AppConfig.Get("matrix_zoom", 100);
InterpolationMode matrixQuality = (InterpolationMode)AppConfig.Get("matrix_quality", 0);
FrameDimension dimension = new FrameDimension(image.FrameDimensionsList[0]);
int frameCount = image.GetFrameCount(dimension);
if (frameCount > 1)
{
var delayPropertyBytes = image.GetPropertyItem(0x5100).Value;
var frameDelay = BitConverter.ToInt32(delayPropertyBytes) * 10;
for (int i = 0; i < frameCount; i++)
{
image.SelectActiveFrame(dimension, i);
mat.GenerateFrame(image);
mat.AddFrame();
device.GenerateFrame(image, matrixZoom, matrixX, matrixY, matrixQuality);
device.AddFrame();
}
StartMatrixTimer();
Logger.WriteLine("Matrix GIF " + fileName);
Logger.WriteLine("GIF Delay:" + frameDelay);
StartMatrixTimer(Math.Max(50, frameDelay));
//image.SelectActiveFrame(dimension, 0);
}
else
{
mat.GenerateFrame(image);
mat.Present();
Logger.WriteLine("Matrix " + fileName);
device.GenerateFrame(image, matrixZoom, matrixX, matrixY, matrixQuality);
device.Present();
}
}

View File

@@ -1,11 +1,14 @@
// Source thanks to https://github.com/vddCore/Starlight with some adjustments from me
using GHelper;
using GHelper.AnimeMatrix.Communication;
using System.Drawing.Drawing2D;
using System.Drawing.Imaging;
using System.Drawing.Text;
using System.Globalization;
using System.Management;
using System.Text;
using static System.Windows.Forms.VisualStyles.VisualStyleElement.Window;
namespace Starlight.AnimeMatrix
{
@@ -103,12 +106,10 @@ namespace Starlight.AnimeMatrix
string model = GetModel();
if (model.Contains("401"))
{
_model = AnimeType.GA401;
MaxColumns = 33;
dx = 1;
MaxRows = 55;
LedCount = 1245;
@@ -392,8 +393,9 @@ namespace Starlight.AnimeMatrix
{
g.CompositingQuality = CompositingQuality.HighQuality;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
using (Font font = new Font("Consolas", 21F, FontStyle.Regular, GraphicsUnit.Pixel))
using (Font font = new Font("Consolas", 22F, FontStyle.Regular, GraphicsUnit.Pixel))
{
SizeF textSize = g.MeasureString(text1, font);
g.DrawString(text1, font, Brushes.White, (MaxColumns * 3 - textSize.Width) + 3, -4);
@@ -408,39 +410,16 @@ namespace Starlight.AnimeMatrix
}
GenerateFrame(bmp, InterpolationMode.Bicubic);
GenerateFrame(bmp);
Present();
}
}
public void GenerateFrame(Image image, InterpolationMode interpolation = InterpolationMode.High)
public void GenerateFrame(Image image, float zoom = 1, int panX = 0, int panY = 0, InterpolationMode quality = InterpolationMode.Default)
{
int width = MaxColumns / 2 * 6;
int height = MaxRows;
int targetWidth = MaxColumns * 2;
float scale;
using (Bitmap bmp = new Bitmap(targetWidth, height))
using (Bitmap bmp = GeneratePicture(image, zoom, panX, panY, quality))
{
scale = Math.Min((float)width / (float)image.Width, (float)height / (float)image.Height);
using (var graph = Graphics.FromImage(bmp))
{
var scaleWidth = (float)(image.Width * scale);
var scaleHeight = (float)(image.Height * scale);
graph.InterpolationMode = interpolation;
graph.CompositingQuality = CompositingQuality.HighQuality;
graph.SmoothingMode = SmoothingMode.AntiAlias;
graph.DrawImage(image, (float)Math.Round(targetWidth - scaleWidth * targetWidth / width), 0, (float)Math.Round(scaleWidth * targetWidth / width), scaleHeight);
}
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < bmp.Width; x++)
@@ -456,9 +435,40 @@ namespace Starlight.AnimeMatrix
}
public Bitmap GeneratePicture(Image image, float zoom = 100, int panX = 0, int panY = 0, InterpolationMode quality = InterpolationMode.Default)
{
int width = MaxColumns * 3;
int height = MaxRows;
int targetWidth = MaxColumns * 2;
float scale;
Bitmap bmp = new Bitmap(targetWidth, height);
{
scale = Math.Min((float)width / (float)image.Width, (float)height / (float)image.Height) * zoom / 100;
using (var graph = Graphics.FromImage(bmp))
{
var scaleWidth = (float)(image.Width * scale);
var scaleHeight = (float)(image.Height * scale);
graph.InterpolationMode = quality;
graph.CompositingQuality = CompositingQuality.HighQuality;
graph.SmoothingMode = SmoothingMode.AntiAlias;
graph.DrawImage(image, (float)Math.Round(targetWidth - (scaleWidth + panX) * targetWidth / width), -panY, (float)Math.Round(scaleWidth * targetWidth / width), scaleHeight);
return bmp;
}
}
}
public void SetLedDiagonal(int x, int y, byte color, int delta = 10)
{
//x+=delta;
//x += delta;
y -= delta;
int dx = (x - y) / 2;
@@ -471,25 +481,8 @@ namespace Starlight.AnimeMatrix
Clear();
InstalledFontCollection installedFontCollection = new InstalledFontCollection();
string familyName;
string familyList = "";
FontFamily[] fontFamilies;
// Get the array of FontFamily objects.
fontFamilies = installedFontCollection.Families;
int count = fontFamilies.Length;
for (int j = 0; j < count; ++j)
{
familyName = fontFamilies[j].Name;
familyList = familyList + familyName;
familyList = familyList + ", ";
}
int maxX = (int)Math.Sqrt(MaxRows * MaxRows + MaxColumns * MaxColumns);
int textHeight;
using (Bitmap bmp = new Bitmap(maxX, MaxRows))
{
@@ -497,11 +490,13 @@ namespace Starlight.AnimeMatrix
{
g.CompositingQuality = CompositingQuality.HighQuality;
g.SmoothingMode = SmoothingMode.AntiAlias;
g.TextRenderingHint = TextRenderingHint.SingleBitPerPixel;
using (Font font = new Font("Consolas", 13F, FontStyle.Regular, GraphicsUnit.Pixel))
using (Font font = new Font("Consolas", 11, FontStyle.Regular, GraphicsUnit.Pixel))
{
SizeF textSize = g.MeasureString(text, font);
g.DrawString(text, font, Brushes.White, 4, 1);
textHeight = (int)textSize.Height;
g.DrawString(text, font, Brushes.White, 4, 0);
}
}
@@ -511,7 +506,7 @@ namespace Starlight.AnimeMatrix
{
var pixel = bmp.GetPixel(x, y);
var color = (pixel.R + pixel.G + pixel.B) / 3;
SetLedDiagonal(x, y, (byte)color);
SetLedDiagonal(x, y, (byte)color, textHeight - 8);
}
}
}