1 | |
2 | type Recraft = { |
3 | apiKey: string; |
4 | }; |
5 | type Base64 = string; |
6 | |
7 | * Inpaint Image |
8 | * |
9 | */ |
10 | export async function main( |
11 | auth: Recraft, |
12 | body: { |
13 | block_nsfw?: false | true; |
14 | calculate_features?: false | true; |
15 | image: { |
16 | base64: Base64; |
17 | type: |
18 | | "image/png" |
19 | | "image/jpeg" |
20 | | "image/gif" |
21 | | "application/pdf" |
22 | | "appication/json" |
23 | | "text/csv" |
24 | | "text/plain" |
25 | | "audio/mpeg" |
26 | | "audio/wav" |
27 | | "video/mp4"; |
28 | name: string; |
29 | }; |
30 | mask: { |
31 | base64: Base64; |
32 | type: |
33 | | "image/png" |
34 | | "image/jpeg" |
35 | | "image/gif" |
36 | | "application/pdf" |
37 | | "appication/json" |
38 | | "text/csv" |
39 | | "text/plain" |
40 | | "audio/mpeg" |
41 | | "audio/wav" |
42 | | "video/mp4"; |
43 | name: string; |
44 | }; |
45 | model?: |
46 | | "refm1" |
47 | | "recraft20b" |
48 | | "recraftv2" |
49 | | "recraftv3" |
50 | | "flux1_1pro" |
51 | | "flux1dev"; |
52 | n?: number; |
53 | prompt: string; |
54 | random_seed?: number; |
55 | response_format?: "url" | "b64_json"; |
56 | style?: |
57 | | "digital_illustration" |
58 | | "icon" |
59 | | "realistic_image" |
60 | | "vector_illustration"; |
61 | style_id?: string; |
62 | substyle?: |
63 | | "2d_art_poster" |
64 | | "3d" |
65 | | "80s" |
66 | | "glow" |
67 | | "grain" |
68 | | "hand_drawn" |
69 | | "infantile_sketch" |
70 | | "kawaii" |
71 | | "pixel_art" |
72 | | "psychedelic" |
73 | | "seamless" |
74 | | "voxel" |
75 | | "watercolor" |
76 | | "broken_line" |
77 | | "colored_outline" |
78 | | "colored_shapes" |
79 | | "colored_shapes_gradient" |
80 | | "doodle_fill" |
81 | | "doodle_offset_fill" |
82 | | "offset_fill" |
83 | | "outline" |
84 | | "outline_gradient" |
85 | | "uneven_fill" |
86 | | "70s" |
87 | | "cartoon" |
88 | | "doodle_line_art" |
89 | | "engraving" |
90 | | "flat_2" |
91 | | "line_art" |
92 | | "linocut" |
93 | | "b_and_w" |
94 | | "enterprise" |
95 | | "hard_flash" |
96 | | "hdr" |
97 | | "motion_blur" |
98 | | "natural_light" |
99 | | "studio_portrait" |
100 | | "line_circuit" |
101 | | "2d_art_poster_2" |
102 | | "engraving_color" |
103 | | "flat_air_art" |
104 | | "hand_drawn_outline" |
105 | | "handmade_3d" |
106 | | "stickers_drawings"; |
107 | text_layout?: { bbox: number[][]; text: string }[]; |
108 | }, |
109 | ) { |
110 | const url = new URL(`https://external.api.recraft.ai/v1/images/inpaint`); |
111 |
|
112 | const formData = new FormData(); |
113 | for (const [k, v] of Object.entries(body)) { |
114 | if (v !== undefined && v !== "") { |
115 | if (["image", "mask"].includes(k)) { |
116 | const { base64, type, name } = v as { |
117 | base64: Base64; |
118 | type: string; |
119 | name: string; |
120 | }; |
121 | formData.append( |
122 | k, |
123 | new Blob([Uint8Array.from(atob(base64), (m) => m.codePointAt(0)!)], { |
124 | type, |
125 | }), |
126 | name, |
127 | ); |
128 | } else { |
129 | formData.append(k, String(v)); |
130 | } |
131 | } |
132 | } |
133 | const response = await fetch(url, { |
134 | method: "POST", |
135 | headers: { |
136 | Authorization: "Bearer " + auth.apiKey, |
137 | }, |
138 | body: formData, |
139 | }); |
140 | if (!response.ok) { |
141 | const text = await response.text(); |
142 | throw new Error(`${response.status} ${text}`); |
143 | } |
144 | return await response.json(); |
145 | } |
146 |
|