Skip to content

Commit

Permalink
update cli create spr
Browse files Browse the repository at this point in the history
  • Loading branch information
Dr.Abc committed Aug 16, 2024
1 parent 999c18e commit 1ffe6cc
Show file tree
Hide file tree
Showing 12 changed files with 199 additions and 145 deletions.
4 changes: 3 additions & 1 deletion SPRView.Net.CLI/Cli/CLICommandManager.cs
Original file line number Diff line number Diff line change
@@ -1,12 +1,14 @@
using CliFx;
namespace SPRView.Net.Cli;

namespace SPRView.Net.CLI.Cli;
public class CLICommandManager
{
public async void Run(string[] args) => await new CliApplicationBuilder()
.AddCommand<ThumbnailCommand>()
.AddCommand<SaveImageCommand>()
.AddCommand<InformationCommand>()
.AddCommand<PreviewCommand>()
.AddCommand<CreateCommand>()
.Build()
.RunAsync(args);
}
46 changes: 46 additions & 0 deletions SPRView.Net.CLI/Cli/CreateCommand.cs
Original file line number Diff line number Diff line change
@@ -0,0 +1,46 @@
using CliFx;
using CliFx.Attributes;
using CliFx.Infrastructure;
using SPRView.Net.Lib.Class;
using SPRView.Net.Lib.Interface;

namespace SPRView.Net.CLI.Cli;

[Command("create", Description = "create a spr from files")]
public class CreateCommand : ICommand
{
[CommandParameter(0, Description = "Images path, Use \",\" connect multiple paths")]
public required string Paths { get; set; }

[CommandParameter(1, Description = "Spr width")]
public required int Width { get; set; }

[CommandParameter(2, Description = "Spr Height")]
public required int Height { get; set; }

[CommandParameter(3, Description = "Path to save spr file")]
public required string SavePath { get; set; }

[CommandOption("type", 't', Description = "Spr type")]
public int Type { get; set; } = (int)ISprite.SpriteType.Parallel;

[CommandOption("format", 'f', Description = "Spr format")]
public int Format { get; set; } = (int)ISprite.SpriteFormat.Normal;

[CommandOption("sync", 's', Description = "Spr sync")]
public bool Sync { get; set; } = true;

[CommandOption("beam length", 'b', Description = "Spr beam lenght")]
public float BeamLenght { get; set; } = 0.0f;

[CommandOption("unpack", 'u', Description = "Unpack multiple frames of images")]
public bool Unpack { get; set; } = false;

public ValueTask ExecuteAsync(IConsole console)
{
using FileStream fs = File.OpenWrite(SavePath);
string[] paths = Array.ConvertAll(Paths.Split(','), s => s.Trim());
CSprite.Save(paths, fs, Width, Height, (ISprite.SpriteFormat)Format, (ISprite.SpriteType)Type, (ISprite.SpriteSynchron)(Sync ? 0 : 1), BeamLenght, Unpack);
return default;
}
}
4 changes: 2 additions & 2 deletions SPRView.Net.CLI/Cli/InformationCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,9 +3,9 @@
using CliFx.Infrastructure;
using Pastel;
using SixLabors.ImageSharp.PixelFormats;
using SPRView.Net.Lib;
using SPRView.Net.Lib.Class;
using System.Drawing;
namespace SPRView.Net.Cli;
namespace SPRView.Net.CLI.Cli;
[Command("information", Description = "Get spr information")]
public class InformationCommand : ICommand
{
Expand Down
4 changes: 2 additions & 2 deletions SPRView.Net.CLI/Cli/PreviewCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -5,8 +5,8 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SPRView.Net.Lib;
namespace SPRView.Net.Cli;
using SPRView.Net.Lib.Class;
namespace SPRView.Net.CLI.Cli;
[Command("preview", Description = "Preview a spr in console")]
public class PreviewCommand : ICommand
{
Expand Down
4 changes: 2 additions & 2 deletions SPRView.Net.CLI/Cli/SaveImageCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -2,8 +2,8 @@
using CliFx.Attributes;
using CliFx.Infrastructure;
using SixLabors.ImageSharp;
using SPRView.Net.Lib;
namespace SPRView.Net.Cli;
using SPRView.Net.Lib.Class;
namespace SPRView.Net.CLI.Cli;
[Command("image", Description = "Save spr to image")]
public class SaveImageCommand : ICommand
{
Expand Down
4 changes: 2 additions & 2 deletions SPRView.Net.CLI/Cli/ThumbnailCommand.cs
Original file line number Diff line number Diff line change
Expand Up @@ -3,8 +3,8 @@
using CliFx.Infrastructure;
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.Processing;
using SPRView.Net.Lib;
namespace SPRView.Net.Cli;
using SPRView.Net.Lib.Class;
namespace SPRView.Net.CLI.Cli;
[Command("thumbnail", Description = "Generate thumbnail form a spr")]
public class ThumbnailCommand : ICommand
{
Expand Down
2 changes: 1 addition & 1 deletion SPRView.Net.CLI/Program.cs
Original file line number Diff line number Diff line change
@@ -1,3 +1,3 @@
using SPRView.Net.Cli;
using SPRView.Net.CLI.Cli;
CLICommandManager cli = new();
cli.Run(args);
1 change: 1 addition & 0 deletions SPRView.Net.Lib/Class/Frame.cs
Original file line number Diff line number Diff line change
@@ -1,5 +1,6 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SPRView.Net.Lib.Class;
using SPRView.Net.Lib.Interface;

namespace SPRView.Net.Lib;
Expand Down
131 changes: 130 additions & 1 deletion SPRView.Net.Lib/Class/Sprite.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,9 @@
using SixLabors.ImageSharp;
using SixLabors.ImageSharp.PixelFormats;
using SixLabors.ImageSharp.Processing;
using SixLabors.ImageSharp.Processing.Processors.Quantization;
using SPRView.Net.Lib.Interface;
namespace SPRView.Net.Lib;
namespace SPRView.Net.Lib.Class;
public class CSprite : ISprite
{
public ISprite.SpriteType Type { get; set; }
Expand Down Expand Up @@ -92,4 +94,131 @@ public Image GetImage(int frame)
}
return m_aryFrames[frame].GetImage();
}
public static void Save(string[] files, Stream stream, int width, int height,
ISprite.SpriteFormat format = ISprite.SpriteFormat.Normal, ISprite.SpriteType type = ISprite.SpriteType.Parallel, ISprite.SpriteSynchron sync = ISprite.SpriteSynchron.Sync,
float beamlength = 0, bool bUnpack = false)
{
//量化
//降低一个维度,以便统一量化
int buffersize = 0;
if (bUnpack)
{
foreach (var path in files)
{
Image frame = Image.Load(path);
buffersize += frame.Frames.Count;
frame.Dispose();
}
//会多一个
buffersize--;
}
else
buffersize = files.Length;
using Image<Rgba32> image = new(width, height * buffersize);
int bufferseek = 0;
for (int i = 0; i < files.Length; i++)
{
var path = files[i];
Image frame = Image.Load(path);
frame.Mutate(x => x.Resize(width, height));
do
{
image.Mutate(x => x.DrawImage(frame, new Point(0, height * bufferseek), 1.0f));
frame.Frames.RemoveFrame(0);
bufferseek++;
} while (frame.Frames.Count > 1);
frame.Dispose();
}
bool isAlphaTest = format == ISprite.SpriteFormat.AlphaTest;
WuQuantizer quantizer = new(new QuantizerOptions
{
Dither = null,
MaxColors = isAlphaTest ? 255 : 256
});
image.Mutate(x => x.Quantize(quantizer));
//生成色板
Dictionary<Rgba32, byte> palette = [];
for (int j = 0; j < image.Height; j++)
{
for (int i = 0; i < image.Width; i++)
{
Rgba32 rgba32 = image[i, j];
if (!palette.ContainsKey(rgba32))
palette.Add(rgba32, (byte)palette.Count);
}
}
if (isAlphaTest)
palette.Add(new Rgba32(0, 0, 255, 255), 255);
//保存
using BinaryWriter writer = new(stream);
//Header
writer.Write(0x50534449);
//Version
writer.Write(0x00000002);
//Type
writer.Write((int)type);
//Format
writer.Write((int)format);
//BoundRadius
float radius = (float)Math.Sqrt(Math.Pow(width, 2) + Math.Pow(height, 2)) / 2;
writer.Write(radius);
//Width
writer.Write(width);
//Height
writer.Write(height);
//Count
writer.Write(buffersize);
//BeamLength
writer.Write(beamlength);
//Sync
writer.Write((int)sync);
//Palette Size
writer.Write((short)palette.Count);
//Palette
foreach (var p in palette.Keys)
{
writer.Write(p.R);
writer.Write(p.G);
writer.Write(p.B);
}
if (palette.Count < 256 && isAlphaTest)
{
for (int i = palette.Count; i < 255; i++)
{
writer.Write((byte)0);
writer.Write((byte)0);
writer.Write((byte)0);
}
writer.Write((byte)0);
writer.Write((byte)0);
writer.Write((byte)255);
}
//保存数据
for (int k = 0; k < buffersize; k++)
{
//Group
writer.Write(0x00000000);
//OriginX
writer.Write(0x00000000);
//OriginY
writer.Write(0x00000000);
//Width
writer.Write(width);
//Height
writer.Write(height);

var startY = k * height;
for (int j = startY; j < startY + height; j++)
{
for (int i = 0; i < width; i++)
{
Rgba32 rgba32 = image[i, j];
if (isAlphaTest && rgba32.A <= 128)
writer.Write(palette.Last().Value);
else
writer.Write(palette[rgba32]);
}
}
}
}
}
4 changes: 4 additions & 0 deletions SPRView.Net.Lib/Interface/ISprite.cs
Original file line number Diff line number Diff line change
Expand Up @@ -41,4 +41,8 @@ public enum SpriteSynchron
abstract public static ISprite Create(Stream stream);
abstract public static ISprite Create(string? path);
abstract public Image GetImage(int frame);

abstract public static void Save(string[] files, Stream stream, int width, int height,
SpriteFormat format = SpriteFormat.Normal, SpriteType type = SpriteType.Parallel, SpriteSynchron sync = SpriteSynchron.Sync,
float beamlength = 0, bool bUnpack = false);
}
2 changes: 1 addition & 1 deletion SPRView.Net/Storage/CStorage.cs
Original file line number Diff line number Diff line change
@@ -1,7 +1,7 @@
using Avalonia.Controls;
using Avalonia.Media;
using SixLabors.ImageSharp.PixelFormats;
using SPRView.Net.Lib;
using SPRView.Net.Lib.Class;
using SPRView.Net.Lib.Interface;
using System;

Expand Down
Loading

0 comments on commit 1ffe6cc

Please sign in to comment.