Add function to turn static images into GIFs

Change-Id: Ib13449f2828babd986414cd56d23e7ecda00d9b4
Reviewed-on: https://git.clicks.codes/c/coded/EmojiUploader/+/293
Reviewed-by: Samuel Shuert <coded@clicks.codes>
Tested-by: Samuel Shuert <coded@clicks.codes>
diff --git a/bun.lockb b/bun.lockb
index 9f2ccdc..6fe4b98 100755
--- a/bun.lockb
+++ b/bun.lockb
Binary files differ
diff --git a/index.ts b/index.ts
index 3bca63b..813febd 100644
--- a/index.ts
+++ b/index.ts
@@ -1,6 +1,37 @@
 import { ChannelType, Client, Collection, Guild, GuildEmoji, GuildInvitableChannelResolvable, IntentsBitField } from 'discord.js';
 import { writeFileSync, readdirSync, readFileSync } from 'fs'
+import Canvas from 'canvas';
+import GIFEncoder from 'gifencoder';
+import Sharp from 'sharp';
 
+async function staticToAnimatedEmoji(imagePath: string): Promise<Buffer> {
+    const image = Sharp(imagePath);
+    const metadata = await image.metadata();
+    const data = await image.raw().toBuffer();
+    if (!metadata.height || !metadata.width) throw new Error(`${imagePath} has no height or width`);
+    const encoder = new GIFEncoder(metadata.width, metadata.height);
+    encoder.setRepeat(0);
+    encoder.start();
+
+    const canvas = Canvas.createCanvas(metadata.width, metadata.height);
+    const ctx = canvas.getContext('2d');
+    const imageData = new Canvas.ImageData(
+        new Uint8ClampedArray(data),
+        canvas.width,
+        canvas.height
+    );
+
+    ctx.putImageData(imageData, 0, 0);
+
+    encoder.addFrame(ctx);
+    encoder.addFrame(ctx);
+
+    encoder.finish();
+
+    let finished = encoder.out.getData();
+
+    return finished;
+}
 
 async function uploadEmoji(guild: Guild, toUpload: {name: string, attachment: Buffer}): Promise<GuildEmoji> {
     const emoji = await guild.emojis.create(toUpload)
@@ -25,7 +56,6 @@
     return guilds;
 }
 
-
 const client = new Client({
     intents: [
         IntentsBitField.Flags.GuildEmojisAndStickers,
diff --git a/package.json b/package.json
index 45599ca..c5570ac 100644
--- a/package.json
+++ b/package.json
@@ -3,12 +3,16 @@
   "module": "index.ts",
   "type": "module",
   "devDependencies": {
+    "@types/gifencoder": "^2.0.3",
     "bun-types": "latest"
   },
   "peerDependencies": {
     "typescript": "^5.0.0"
   },
   "dependencies": {
-    "discord.js": "^14.14.1"
+    "canvas": "^2.11.2",
+    "discord.js": "^14.14.1",
+    "gifencoder": "^2.0.1",
+    "sharp": "^0.33.2"
   }
 }
\ No newline at end of file