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 :) // Source thanks to https://github.com/vddCore/Starlight :)
using System.Diagnostics;
using System.Text; using System.Text;
using Starlight.Communication; using Starlight.Communication;
@@ -71,13 +72,40 @@ namespace Starlight.AnimeMatrix
public int LedCount => 1450; public int LedCount => 1450;
public int Rows => 61; 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() public AnimeMatrixDevice()
: base(0x0B05, 0x193B, 640) : 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) public void SendRaw(params byte[] data)
{ {
Set(Packet<AnimeMatrixPacket>(data)); Set(Packet<AnimeMatrixPacket>(data));
@@ -208,6 +236,41 @@ namespace Starlight.AnimeMatrix
SetBuiltInAnimation(enable); SetBuiltInAnimation(enable);
Set(Packet<AnimeMatrixPacket>(0xC5, animation.AsByte)); 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) private void EnsureRowInRange(int row)
{ {

View File

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

View File

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

View File

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

View File

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

View File

@@ -5,6 +5,8 @@ using System.Timers;
using System.Drawing.Imaging; using System.Drawing.Imaging;
using System.CodeDom.Compiler; using System.CodeDom.Compiler;
using System.Drawing; using System.Drawing;
using System;
using System.Globalization;
namespace GHelper namespace GHelper
{ {
@@ -21,11 +23,15 @@ namespace GHelper
static System.Timers.Timer aTimer = default!; static System.Timers.Timer aTimer = default!;
static System.Timers.Timer matrixTimer = default!;
public string perfName = "Balanced"; public string perfName = "Balanced";
Fans fans; Fans fans;
Keyboard keyb; Keyboard keyb;
AnimeMatrixDevice mat = new AnimeMatrixDevice();
public SettingsForm() public SettingsForm()
{ {
@@ -98,54 +104,54 @@ namespace GHelper
void SetMatrixPicture(string fileName) void SetMatrixPicture(string fileName)
{ {
int width = 34 * 3; Image image;
int height = 61;
float scale;
Bitmap image;
try try
{ {
using (var bmpTemp = (Bitmap)Image.FromFile(fileName)) using (var fs = new FileStream(fileName, FileMode.Open))
{ {
image = new Bitmap(bmpTemp); var ms = new MemoryStream();
fs.CopyTo(ms);
Bitmap canvas = new Bitmap(width, height); ms.Position = 0;
image = Image.FromStream(ms);
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);
}
}
mat.Present();
mat.Dispose();
} }
} } catch
catch
{ {
Debug.WriteLine("Error loading picture"); 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)(() => Thread t = new Thread((ThreadStart)(() =>
{ {
OpenFileDialog of = new OpenFileDialog(); 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) if (of.ShowDialog() == DialogResult.OK)
{ {
Program.config.setConfig("matrix_picture", of.FileName); Program.config.setConfig("matrix_picture", of.FileName);
@@ -192,7 +198,7 @@ namespace GHelper
int brightness = comboMatrix.SelectedIndex; int brightness = comboMatrix.SelectedIndex;
int running = comboMatrixRunning.SelectedIndex; int running = comboMatrixRunning.SelectedIndex;
var mat = new AnimeMatrixDevice(); //var mat = new AnimeMatrixDevice();
BuiltInAnimation animation = new BuiltInAnimation( BuiltInAnimation animation = new BuiltInAnimation(
(BuiltInAnimation.Running)running, (BuiltInAnimation.Running)running,
@@ -222,7 +228,7 @@ namespace GHelper
} }
} }
mat.Dispose(); //mat.Dispose();
Program.config.setConfig("matrix_brightness", comboMatrix.SelectedIndex); Program.config.setConfig("matrix_brightness", comboMatrix.SelectedIndex);
Program.config.setConfig("matrix_running", comboMatrixRunning.SelectedIndex); Program.config.setConfig("matrix_running", comboMatrixRunning.SelectedIndex);