-
Notifications
You must be signed in to change notification settings - Fork 0
/
Copy pathvaporwaver.ts
174 lines (149 loc) · 6.69 KB
/
vaporwaver.ts
1
2
3
4
5
6
7
8
9
10
11
12
13
14
15
16
17
18
19
20
21
22
23
24
25
26
27
28
29
30
31
32
33
34
35
36
37
38
39
40
41
42
43
44
45
46
47
48
49
50
51
52
53
54
55
56
57
58
59
60
61
62
63
64
65
66
67
68
69
70
71
72
73
74
75
76
77
78
79
80
81
82
83
84
85
86
87
88
89
90
91
92
93
94
95
96
97
98
99
100
101
102
103
104
105
106
107
108
109
110
111
112
113
114
115
116
117
118
119
120
121
122
123
124
125
126
127
128
129
130
131
132
133
134
135
136
137
138
139
140
141
142
143
144
145
146
147
148
149
150
151
152
153
154
155
156
157
158
159
160
161
162
163
164
165
166
167
168
169
170
171
172
173
174
import { spawn } from 'child_process';
import * as fs from 'fs';
const validGradients: string[] = [
"none",
"autumn",
"bone",
"jet",
"winter",
"rainbow",
"ocean",
"summer",
"spring",
"cool",
"hsv",
"pink",
"hot",
"parula",
"magma",
"inferno",
"plasma",
"viridis",
"cividis",
"deepgreen"
];
interface IFlag {
// the background image of the vaporwave image
background?: string;
// the misc image of the vaporwave image
misc?: string;
// the misc image's x position
miscPosX?: number;
// the misc image's y position
miscPosY?: number;
// the misc image's scale
miscScale?: number;
// the misc image's rotation
miscRotate?: number;
// the character image of the vaporwave image (required)
characterPath: string;
// the character image's x position
characterXPos?: Number;
// the character image's y position
characterYPos?: number;
// the character image's scale
characterScale?: number;
// the character image's rotation
characterRotate?: number;
// the character image's glitch value
characterGlitch?: number;
// the character image's glitch seed value
characterGlitchSeed?: number;
// the character image's gradient value accorded to cvt color gradients maps
characterGradient?: string;
// crt effect on the vaporwave image
crt?: boolean;
// output path of the vaporwave image
outputPath?: fs.PathLike;
};
type DefaultValues = Pick<IFlag, 'characterPath' | 'miscPosX' | 'miscPosY' | 'miscScale' | 'miscRotate' | 'characterYPos' | 'characterXPos' | 'characterScale' | 'crt' | 'outputPath' | 'characterGlitch' | 'characterRotate' | 'characterGlitchSeed'>;
const defaultFlag: DefaultValues = {
characterPath: '',
miscPosX: 0,
miscPosY: 0,
miscScale: 100,
miscRotate: 0,
characterXPos: 0,
characterYPos: 0,
characterScale: 100,
characterRotate: 0,
characterGlitch: .1,
characterGlitchSeed: 0,
crt: false,
outputPath: "./output/vaporwave.png"
};
export const vaporwaver = (flags: IFlag = defaultFlag) => {
if (!flags.background) flags.background = "default";
if (!fs.existsSync('./picts/backgrounds/' + flags.background + '.png'))
throw new Error("Background path is not valid.");
// check if output path is not a valid pathlike or contains malicious characters
if (!flags.outputPath || flags.outputPath.toString().includes('..') || flags.outputPath.toString().includes('&'))
throw new Error("Output path is not valid.");
// check if the path of character file exists
if (!fs.existsSync(flags.characterPath))
throw new Error("Character path is not valid.");
// check if the character is a png file according to the base64 header
if (fs.readFileSync(flags.characterPath).toString('base64').slice(0, 8) !== 'iVBORw0K')
throw new Error("Character file is not a png file.");
// if gradient is specified, check if it is valid
flags.characterGradient = flags.characterGradient?.toLocaleLowerCase();
if (flags.characterGradient && !validGradients.includes(flags.characterGradient))
throw new Error("Gradient is not valid.");
// if misc is specified, check if it exists
if (flags.misc && !fs.existsSync('./picts/miscs/' + flags.misc + '.png'))
throw new Error("Misc path is not valid.");
// check if miscposx and miscposy are between -100 and 100
if (flags.miscPosX && (flags.miscPosX < -100 || flags.miscPosX > 100))
throw new Error("Misc X position is not valid. The value must be between -100 and 100.");
if (flags.miscPosY && (flags.miscPosY < -100 || flags.miscPosY > 100))
throw new Error("Misc Y position is not valid. The value must be between -100 and 100.");
// check if miscscale is between 1 and 200
if (flags.miscScale && (flags.miscScale < 1 || flags.miscScale > 200))
throw new Error("Misc scale value is not valid. The value must be between 1 and 200.");
// check if miscrotate is between -360 and 360
if (flags.miscRotate && (flags.miscRotate < -360 || flags.miscRotate > 360))
throw new Error("Misc rotate value is not valid. The value must be between -360 and 360.");
// check if characterxpos and characterypos are between -100 and 100
if (flags.characterXPos && (flags.characterXPos < -100 || flags.characterXPos > 100))
throw new Error("Character X position is not valid. The value must be between -100 and 100.");
if (flags.characterYPos && (flags.characterYPos < -100 || flags.characterYPos > 100))
throw new Error("Character Y position is not valid. The value must be between -100 and 100.");
// check if characterscale is between 1 and 200
if (flags.characterScale && (flags.characterScale < 1 || flags.characterScale > 200))
throw new Error("Character scale value is not valid. The value must be between 1 and 200.");
// check if characterrotate is between -360 and 360
if (flags.characterRotate && (flags.characterRotate < -360 || flags.characterRotate > 360))
throw new Error("Character rotate value is not valid. The value must be between -360 and 360.");
// check if characterglitch is between .1 and 10
if (flags.characterGlitch && (flags.characterGlitch < .1 || flags.characterGlitch > 10))
throw new Error("Character glitch value is not valid. The value must be between .1 and 10.");
// check if characterglitchseed is between 0 and 100
if (flags.characterGlitchSeed && (flags.characterGlitchSeed < 0 || flags.characterGlitchSeed > 100))
throw new Error("Character glitch seed value is not valid. The value must be between 0 and 100.");
// execute a python script to generate the vaporwave image
try {
const options = { timeout: 5000 };
const pyScript = `./vaporwaver.py`;
const pyScriptArgs = [
`-b=${flags.background}`,
`-c=${flags.characterPath}`,
`-m=${flags.misc || 'none'}`,
`-mx=${flags.miscPosX || 0}`,
`-my=${flags.miscPosY || 0}`,
`-ms=${flags.miscScale || 100}`,
`-mr=${flags.miscRotate || 0}`,
`-cx=${flags.characterXPos || 0}`,
`-cy=${flags.characterYPos || 0}`,
`-cs=${flags.characterScale || 100}`,
`-cr=${flags.characterRotate || 0}`,
`-cg=${flags.characterGlitch || .1}`,
`-cgs=${flags.characterGlitchSeed || 0}`,
`-cgd=${flags.characterGradient || 'none'}`,
`-crt=${flags.crt || false}`,
`-o=${flags.outputPath || './output/vaporwave.png'}`,
];
spawn("py", [pyScript, ...pyScriptArgs], options);
} catch (e: any) {
throw new Error(e.stderr.toString());
};
};