Skip to content

Commit

Permalink
add back /tint
Browse files Browse the repository at this point in the history
  • Loading branch information
3vorp committed Oct 7, 2023
1 parent 1f9fbf7 commit 6636ea8
Show file tree
Hide file tree
Showing 2 changed files with 64 additions and 61 deletions.
18 changes: 14 additions & 4 deletions src/commands/images/tint.ts
Original file line number Diff line number Diff line change
@@ -1,11 +1,13 @@
import { SlashCommand } from "@interfaces";
import { ChatInputCommandInteraction, EmbedBuilder } from "@client";
import { ChatInputCommandInteraction, Message } from "@client";
import { SlashCommandBuilder } from "discord.js";
import { mcColorsOptions, multiplyAttachment } from "@images/multiply";
import { mcColorsOptions, multiplyToAttachment } from "@images/multiply";
import getImage from "@helpers/getImage";
import { imageButtons } from "@helpers/buttons";
export const command: SlashCommand = {
data: new SlashCommandBuilder()
.setName("tint")
.setDescription(`Tint a grayscale image to a minecraft color`)
.setDescription(`Tint a grayscale image to a Minecraft color`)
.addStringOption((option) =>
option
.setName("color")
Expand All @@ -16,5 +18,13 @@ export const command: SlashCommand = {
.addAttachmentOption((o) =>
o.setName("image").setDescription("The image to tint").setRequired(false),
),
async execute(interaction: ChatInputCommandInteraction) {},
async execute(interaction: ChatInputCommandInteraction) {
await interaction.deferReply();
const url = await getImage(interaction);
const file = await multiplyToAttachment(url, interaction.options.getString("color"));
await interaction.editReply({
files: [file],
components: [imageButtons],
}).then((message: Message) => message.deleteButton());
},
};
107 changes: 50 additions & 57 deletions src/helpers/images/multiply.ts
Original file line number Diff line number Diff line change
@@ -1,88 +1,81 @@
import { EmbedBuilder } from "@client";
import { createCanvas, loadImage } from "@napi-rs/canvas";
import { AttachmentBuilder } from "discord.js";
import ColorManager from "@images/colors";
import getDimensions from "./getDimensions";
import { ImageSource } from "./magnify";

export enum MCColors {
Foliage = "#5BAB46",
FoliageCold = "#60A17B",
FoliageHot = "#1ABF00",
FoliageDry = "#AEA42A",
Grass = "#7CBD6B",
GrassCold = "#80B497",
GrassHot = "#47CD33",
GrassDry = "#BFB755",
DyeWhite = "#F9FFFE",
DyeOrange = "#F9801D",
DyeMagenta = "#C74EBD",
DyeLightBlue = "#3AB3DA",
DyeYellow = "#FED83D",
DyeLime = "#80C71F",
DyePink = "#F38BAA",
DyeGray = "#474F52",
DyeLightGray = "#9D9D97",
DyeCyan = "#169C9C",
DyePurple = "#8932B8",
DyeBlue = "#3C44AA",
DyeBrown = "#835432",
DyeGreen = "#5E7C16",
DyeRed = "#B02E26",
DyeBlack = "#1D1D21",
export const mcColors = {
Foliage: "#5BAB46",
ColdFoliage: "#60A17B",
HotFoliage: "#1ABF00",
DryFoliage: "#AEA42A",
Grass: "#7CBD6B",
ColdGrass: "#80B497",
HotGrass: "#47CD33",
DryGrass: "#BFB755",
WhiteDye: "#F9FFFE",
OrangeDye: "#F9801D",
MagentaDye: "#C74EBD",
LightBlueDye: "#3AB3DA",
YellowDye: "#FED83D",
LimeDye: "#80C71F",
PinkDye: "#F38BAA",
GrayDye: "#474F52",
LightGrayDye: "#9D9D97",
CyanDye: "#169C9C",
PurpleDye: "#8932B8",
BlueDye: "#3C44AA",
BrownDye: "#835432",
GreenDye: "#5E7C16",
RedDye: "#B02E26",
BlackDye: "#1D1D21",
}

export const mcColorsOptions: { name: string; value: string }[] = Object.keys(MCColors).map(
export const mcColorsOptions: { name: string; value: string }[] = Object.keys(mcColors).map(
(name) => {
//a cheeky regex for formatting
return {
name: name.replace(/([a-z])([A-Z])/g, "$1 $2"),
value: MCColors[name as keyof typeof MCColors],
value: mcColors[name as keyof typeof mcColors],
};
},
);

type MultiplyOptions = {
url: string;
embed?: EmbedBuilder;
name?: string;
color: string;
};

export async function multiplyAttachment(
options: MultiplyOptions,
): Promise<[AttachmentBuilder, EmbedBuilder]> {
const dimension = await getDimensions(options.url);
const canvas = createCanvas(dimension.width, dimension.height);
export async function multiply(origin: ImageSource, color: string) {
const imageToDraw = await loadImage(origin);
const canvas = createCanvas(imageToDraw.width, imageToDraw.height);
const context = canvas.getContext("2d");

context.imageSmoothingEnabled = false;
const imageToDraw = await loadImage(options.url);

context.drawImage(imageToDraw, 0, 0, dimension.width, dimension.height);
context.drawImage(imageToDraw, 0, 0, imageToDraw.width, imageToDraw.height);
context.globalCompositeOperation = "multiply";

context.fillStyle = options.color;
context.fillRect(0, 0, dimension.width, dimension.height);
context.fillStyle = color;
context.fillRect(0, 0, imageToDraw.width, imageToDraw.height);

const data = context.getImageData(0, 0, dimension.width, dimension.height);
const data = context.getImageData(0, 0, imageToDraw.width, imageToDraw.height);

for (let i = 0; i < data.data.length; i += 4) {
const red = data.data[i];
const green = data.data[i + 1];
const blue = data.data[i + 2];
const r = data.data[i];
const g = data.data[i + 1];
const b = data.data[i + 2];

const hex = new ColorManager({ rgb: { r: red, g: green, b: blue } }).toHEX().value;
if (hex.toUpperCase() == options.color.substring(1)) {
const hex = new ColorManager({ rgb: { r, g, b } }).toHEX().value;
if (hex.toUpperCase() == color.substring(1)) {
data.data[i + 3] = 0;
}
}

context.putImageData(data, 0, 0);

return [
new AttachmentBuilder(canvas.toBuffer("image/png"), {
name: `${options.name || "tinted.png"}`,
}),
options.embed,
];
return canvas.toBuffer("image/png");
}

export async function multiplyToAttachment(
origin: ImageSource,
color: string,
name = "tinted.png",
) {
const buf = await multiply(origin, color);
return new AttachmentBuilder(buf, { name });
}

0 comments on commit 6636ea8

Please sign in to comment.