Added support for animated GIF in animatrix

This commit is contained in:
seerge
2023-03-05 23:14:48 +01:00
parent 52b07843a2
commit 321bc2623d
6 changed files with 122 additions and 49 deletions

View File

@@ -1,5 +1,6 @@
// Source thanks to https://github.com/vddCore/Starlight :)
using System.Diagnostics;
using System.Text;
using Starlight.Communication;
@@ -71,13 +72,40 @@ namespace Starlight.AnimeMatrix
public int LedCount => 1450;
public int Rows => 61;
private readonly byte[] _displayBuffer = new byte[UpdatePageLength * 3];
private byte[] _displayBuffer = new byte[UpdatePageLength * 3];
private List<byte[]> frames = new List<byte[]>();
private int frameIndex = 0;
public AnimeMatrixDevice()
: base(0x0B05, 0x193B, 640)
{
}
public byte[] GetBuffer()
{
return _displayBuffer;
}
public void PresentNextFrame()
{
if (frameIndex >= frames.Count) frameIndex = 0;
_displayBuffer = frames[frameIndex];
Present();
frameIndex++;
}
public void ClearFrames()
{
frames.Clear();
frameIndex = 0;
}
public void AddFrame()
{
frames.Add(_displayBuffer.ToArray());
}
public void SendRaw(params byte[] data)
{
Set(Packet<AnimeMatrixPacket>(data));
@@ -209,6 +237,41 @@ namespace Starlight.AnimeMatrix
Set(Packet<AnimeMatrixPacket>(0xC5, animation.AsByte));
}
public void GenerateFrame(Image image)
{
int width = 34 * 3;
int height = 61;
float scale;
Bitmap canvas = new Bitmap(width, height);
scale = Math.Min((float)width / (float)image.Width, (float)height / (float)image.Height);
var graph = Graphics.FromImage(canvas);
var scaleWidth = (int)(image.Width * scale);
var scaleHeight = (int)(image.Height * scale);
graph.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
graph.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graph.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
graph.DrawImage(image, ((int)width - scaleWidth), ((int)height - scaleHeight) / 2, scaleWidth, scaleHeight);
Bitmap bmp = new Bitmap(canvas, 34, 61);
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < bmp.Width; x++)
{
var pixel = bmp.GetPixel(x, y);
byte color = (byte)((pixel.R + pixel.G + pixel.B) / 3);
SetLedPlanar(x, y, color);
}
}
}
private void EnsureRowInRange(int row)
{
if (row < 0 || row >= Rows)

View File

@@ -3,7 +3,7 @@
public class Aura
{
static byte[] MESSAGE_SET = { 0x5d, 0xb5 };
static byte[] MESSAGE_SET = { 0x5d, 0xb5, 0,0,0 };
static byte[] MESSAGE_APPLY = { 0x5d, 0xb4};
public const int Static = 0;

View File

@@ -15,7 +15,7 @@
<AssemblyName>GHelper</AssemblyName>
<PlatformTarget>x64</PlatformTarget>
<ProduceReferenceAssembly>False</ProduceReferenceAssembly>
<AssemblyVersion>0.15.1</AssemblyVersion>
<AssemblyVersion>0.16</AssemblyVersion>
<AllowUnsafeBlocks>True</AllowUnsafeBlocks>
</PropertyGroup>

View File

@@ -10,6 +10,7 @@
{"screenshot", "Screenshot"},
{"play", "Play/Pause"},
{"aura", "Aura"},
{"ghelper", "Open GHelper"},
{"custom", "Custom"}
};

View File

@@ -159,6 +159,9 @@ namespace GHelper
case "performance":
settingsForm.BeginInvoke(settingsForm.CyclePerformanceMode);
break;
case "ghelper":
settingsForm.BeginInvoke(SettingsToggle);
break;
case "custom":
CustomKey(name);
break;

View File

@@ -5,6 +5,8 @@ using System.Timers;
using System.Drawing.Imaging;
using System.CodeDom.Compiler;
using System.Drawing;
using System;
using System.Globalization;
namespace GHelper
{
@@ -21,11 +23,15 @@ namespace GHelper
static System.Timers.Timer aTimer = default!;
static System.Timers.Timer matrixTimer = default!;
public string perfName = "Balanced";
Fans fans;
Keyboard keyb;
AnimeMatrixDevice mat = new AnimeMatrixDevice();
public SettingsForm()
{
@@ -98,54 +104,54 @@ namespace GHelper
void SetMatrixPicture(string fileName)
{
int width = 34 * 3;
int height = 61;
float scale;
Bitmap image;
Image image;
try
{
using (var bmpTemp = (Bitmap)Image.FromFile(fileName))
using (var fs = new FileStream(fileName, FileMode.Open))
{
image = new Bitmap(bmpTemp);
Bitmap canvas = new Bitmap(width, height);
scale = Math.Min((float)width / (float)image.Width, (float)height / (float)image.Height);
var graph = Graphics.FromImage(canvas);
var scaleWidth = (int)(image.Width * scale);
var scaleHeight = (int)(image.Height * scale);
graph.InterpolationMode = System.Drawing.Drawing2D.InterpolationMode.High;
graph.CompositingQuality = System.Drawing.Drawing2D.CompositingQuality.HighQuality;
graph.SmoothingMode = System.Drawing.Drawing2D.SmoothingMode.AntiAlias;
graph.DrawImage(image, ((int)width - scaleWidth), ((int)height - scaleHeight) / 2, scaleWidth, scaleHeight);
Bitmap bmp = new Bitmap(canvas, 34, 61);
var mat = new AnimeMatrixDevice();
mat.SetBuiltInAnimation(false);
for (int y = 0; y < bmp.Height; y++)
{
for (int x = 0; x < bmp.Width; x++)
{
var pixel = bmp.GetPixel(x, y);
byte color = (byte)((pixel.R + pixel.G + pixel.B) / 3);
mat.SetLedPlanar(x, y, color);
var ms = new MemoryStream();
fs.CopyTo(ms);
ms.Position = 0;
image = Image.FromStream(ms);
}
}
mat.Present();
mat.Dispose();
}
}
catch
} catch
{
Debug.WriteLine("Error loading picture");
return;
}
mat.SetBuiltInAnimation(false);
mat.ClearFrames();
FrameDimension dimension = new FrameDimension(image.FrameDimensionsList[0]);
int frameCount = image.GetFrameCount(dimension);
if (frameCount > 1)
{
for (int i = 0; i < frameCount; i++)
{
image.SelectActiveFrame(dimension, i);
mat.GenerateFrame(image);
mat.AddFrame();
}
matrixTimer = new System.Timers.Timer(50);
matrixTimer.Enabled = true;
matrixTimer.Elapsed += delegate
{
mat.PresentNextFrame();
};
} else
{
if (matrixTimer is not null)
{
matrixTimer.Enabled = false;
matrixTimer.Dispose();
}
mat.GenerateFrame(image);
mat.Present();
}
@@ -157,7 +163,7 @@ namespace GHelper
Thread t = new Thread((ThreadStart)(() =>
{
OpenFileDialog of = new OpenFileDialog();
of.Filter = "Image Files (*.bmp;*.jpg;*.jpeg,*.png)|*.BMP;*.JPG;*.JPEG;*.PNG";
of.Filter = "Image Files (*.bmp;*.jpg;*.jpeg,*.png,*.gif)|*.BMP;*.JPG;*.JPEG;*.PNG;*.GIF";
if (of.ShowDialog() == DialogResult.OK)
{
Program.config.setConfig("matrix_picture", of.FileName);
@@ -192,7 +198,7 @@ namespace GHelper
int brightness = comboMatrix.SelectedIndex;
int running = comboMatrixRunning.SelectedIndex;
var mat = new AnimeMatrixDevice();
//var mat = new AnimeMatrixDevice();
BuiltInAnimation animation = new BuiltInAnimation(
(BuiltInAnimation.Running)running,
@@ -222,7 +228,7 @@ namespace GHelper
}
}
mat.Dispose();
//mat.Dispose();
Program.config.setConfig("matrix_brightness", comboMatrix.SelectedIndex);
Program.config.setConfig("matrix_running", comboMatrixRunning.SelectedIndex);