Skip to content

Commit

Permalink
update for localdb, tmp, and frooxengine.store
Browse files Browse the repository at this point in the history
  • Loading branch information
astralchan committed Dec 16, 2023
1 parent 961f7da commit 358fdad
Show file tree
Hide file tree
Showing 6 changed files with 59 additions and 42 deletions.
2 changes: 0 additions & 2 deletions .gitignore
Original file line number Diff line number Diff line change
@@ -1,4 +1,2 @@
bin/*
obj/*
*.ide
.vs/
12 changes: 0 additions & 12 deletions .vscode/settings.json

This file was deleted.

10 changes: 10 additions & 0 deletions CONTRIBUTERS.md
Original file line number Diff line number Diff line change
@@ -0,0 +1,10 @@
* [art0007i](https://github.com/art0007i)
Help with making mod and teaching about gif parsing
* [LeCloutPanda](https://github.com/LeCloutPanda)
Ported to Resonite
* [zkxs](https://github.com/zkxs)
Compatibility for unix-like filesystem / etc
* [Psychpsyo](https://github.com/Psychpsyo)
Made nice thumbnail when saving gif (first frame instead of entire sprite preview)
* [989onan](https://github.com/989onan)
Added support for resdb links and switched from system temp folder
71 changes: 44 additions & 27 deletions GifImporter.cs
Original file line number Diff line number Diff line change
@@ -1,30 +1,31 @@
// vim: ts=4 sw=4 noet cc=120

using System;
using System.Threading.Tasks;
using System;
using System.IO;
using System.Threading.Tasks;
using System.Drawing.Imaging;
using System.Drawing;
using FrooxEngine;

using HarmonyLib;
using ResoniteModLoader;

using FrooxEngine;
using FrooxEngine.Store;
using Elements.Core;
using System.Text;

namespace GifImporter;

public class GifImporter : ResoniteMod
{
// Port by LeCloutPanda
public override string Name => "GifImporter";
public override string Author => "astral";
public override string Version => "1.1.5";
public override string Link => "https://git.astralchan.xyz/astral/GifImporter";
public override string Version => "1.1.6";
public override string Link => "https://github.com/astralchan/GifImporter";

[AutoRegisterConfigKey]
public static ModConfigurationKey<bool> KEY_SQUARE = new ModConfigurationKey<bool>(
"Square spritesheet",
"Generate square spritesheet (sometimes has bigger size)",
() => false);
"Generate square spritesheet",
() => true);
public static ModConfiguration? config;

public override void OnEngineInit() {
Expand All @@ -45,31 +46,47 @@ public static bool Prefix(string path, ref Task __result, Slot targetSlot, float
LocalDB localDB = targetSlot.World.Engine.LocalDB;

// Local file import vs URL import
if (uri.Scheme == "file" && string.Equals(Path.GetExtension(path), ".gif",
StringComparison.OrdinalIgnoreCase)) {
if (uri.Scheme == "file") {
// Check file header
using (FileStream fs = new FileStream(path, FileMode.Open, FileAccess.Read)) {
byte[] headerBytes = new byte[6]; // GIF header is 6 bytes
int bytesRead = fs.Read(headerBytes, 0, headerBytes.Length);

if (bytesRead != headerBytes.Length)
throw new Exception("File too short to be a gif");

string header = Encoding.ASCII.GetString(headerBytes);

if (header != "GIF87a" && header != "GIF89a")
throw new Exception("Magic number doesn't match GIF magic number");

validGif = true;
}
image = Image.FromStream(File.OpenRead(path));
validGif = true;
} else if (uri.Scheme == "http" || uri.Scheme == "https")
{
} else if (uri.Scheme == "http" || uri.Scheme == "https" || uri.Scheme == "resdb") {
var client = new System.Net.WebClient();
image = Image.FromStream(client.OpenRead(uri));
var type = client.ResponseHeaders.Get("content-type");
validGif = type == "image/gif";
}
else if (uri.Scheme == "resdb"){
} else if (uri.Scheme == "resdb") {
validGif = true;
}

if (!validGif) {
Debug($"{path} is not a gif, returning true");
image?.Dispose();
return true;
}

__result = targetSlot.StartTask(async delegate () {
await default(ToBackground);

// Load the image
if (uri.Scheme == "resdb") {
Debug($"Awaiting asset from resdb uri...");
image = Image.FromStream(await localDB.TryOpenAsset(uri));
}

int frameCount = 0;
float frameDelay = 0;
var frameWidth = 0;
Expand All @@ -80,7 +97,6 @@ public static bool Prefix(string path, ref Task __result, Slot targetSlot, float
const int PropertyTagFrameDelay = 0x5100;
Bitmap? spriteSheet = null;
string spritePath = Path.Combine(localDB.TemporaryPath, Path.GetFileName(path));


try {
frameCount = image!.GetFrameCount(FrameDimension.Time);
Expand All @@ -107,14 +123,16 @@ public static bool Prefix(string path, ref Task __result, Slot targetSlot, float
spriteSheet = new Bitmap(frameWidth * gifCols, frameHeight * gifRows);
int delay = 0;
using (Graphics g = Graphics.FromImage(spriteSheet)) {
for (int i = 0; i < gifRows; i++) for (int j = 0; j < gifCols; j++) {
if (i * gifCols + j >= frameCount) break;
//convert 4 bit value to integer
var duration = BitConverter.ToInt32(times, 4 * ((i * gifCols) + j));
//Set the write frame before we save it
image.SelectActiveFrame(FrameDimension.Time, i * gifCols + j);
g.DrawImage(image, frameWidth * j, frameHeight * i);
delay += duration;
for (int i = 0; i < gifRows; i++)
for (int j = 0; j < gifCols; j++) {
if (i * gifCols + j >= frameCount)
break;
// Convert 4-bit value to integer
var duration = BitConverter.ToInt32(times, 4 * ((i * gifCols) + j));
// Set the write frame before we save it
image.SelectActiveFrame(FrameDimension.Time, i * gifCols + j);
g.DrawImage(image, frameWidth * j, frameHeight * i);
delay += duration;
}
frameDelay = 100 * frameCount / delay;
}
Expand All @@ -127,7 +145,6 @@ public static bool Prefix(string path, ref Task __result, Slot targetSlot, float
}

Debug($"Image saved as {spritePath}");


Uri localUri = await localDB.ImportLocalAssetAsync(spritePath,
LocalDB.ImportLocation.Copy).ConfigureAwait(continueOnCapturedContext: false);
Expand Down
4 changes: 4 additions & 0 deletions GifImporter.csproj
Original file line number Diff line number Diff line change
Expand Up @@ -21,6 +21,7 @@
<!-- windows steam -->
<ResonitePath Condition="Exists('C:\Program Files (x86)\Steam\steamapps\common\Resonite\')">C:\Program Files (x86)\Steam\steamapps\common\Resonite\</ResonitePath>
<ResonitePath Condition="Exists('D:\SteamLibrary\steamapps\common\Resonite\')">D:\SteamLibrary\steamapps\common\Resonite\</ResonitePath>
<ResonitePath Condition="Exists('E:\SteamLibrary\steamapps\common\Resonite\')">E:\SteamLibrary\steamapps\common\Resonite\</ResonitePath>
<!-- windows standalone -->
<ResonitePath Condition="Exists('C:\Resonite\app\')">C:\Resonite\app\</ResonitePath>
</PropertyGroup>
Expand All @@ -41,6 +42,9 @@
<Reference Include="FrooxEngine">
<HintPath>$(ResonitePath)Resonite_Data\Managed\FrooxEngine.dll</HintPath>
</Reference>
<Reference Include="FrooxEngine.Store">
<HintPath>$(ResonitePath)Resonite_Data\Managed\FrooxEngine.Store.dll</HintPath>
</Reference>
</ItemGroup>

<Target Name="PostBuild" AfterTargets="PostBuildEvent" Condition="'$(CopyToMods)'=='true'">
Expand Down
2 changes: 1 addition & 1 deletion README.md
Original file line number Diff line number Diff line change
Expand Up @@ -5,7 +5,7 @@ essentially import gif images. It converts gifs to a spritesheet then adds the a


Related issue on [NeosPublic](https://github.com/Neos-Metaverse/NeosPublic/) issue tracker:
[261](https://github.com/Neos-Metaverse/NeosPublic/issues/261) *I am keeping this here as it still relates*
[261](https://github.com/Neos-Metaverse/NeosPublic/issues/261)

## Usage

Expand Down

0 comments on commit 358fdad

Please sign in to comment.