Skip to content

Commit 0ecde29

Browse files
authored
Enabling a WASM module to render svg images to png (#245)
1 parent 2e082ae commit 0ecde29

5 files changed

Lines changed: 61 additions & 4 deletions

File tree

emails/templates/tickets/ticket-confirmation.tsx

Lines changed: 4 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -54,12 +54,12 @@ export const TicketConfirmation = ({
5454
{eventName}
5555
</Text>
5656

57-
<Row>
57+
<Container className="px-20 mb-16">
5858
<Img
59-
className="px-20 mb-16"
60-
src={`https://svg-renderer.communityos.io/qr/svg/${userTicketId}`}
59+
className="w-full mx-auto"
60+
src={`https://svg-renderer.communityos.io/qr/png/${userTicketId}`}
6161
/>
62-
</Row>
62+
</Container>
6363

6464
<Text className="text-xl mb-16">
6565
Recuerda llevar este ticket contigo el día del evento. <br />

package-lock.json

Lines changed: 10 additions & 0 deletions
Some generated files are not rendered by default. Learn more about customizing how changed files appear on GitHub.

package.json

Lines changed: 1 addition & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -84,6 +84,7 @@
8484
"@pothos/plugin-authz": "^3.5.8",
8585
"@pothos/plugin-dataloader": "^3.19.0",
8686
"@pothos/plugin-tracing": "^0.5.8",
87+
"@resvg/resvg-wasm": "^2.6.2",
8788
"@sanity/client": "^6.7.0",
8889
"@tsndr/cloudflare-worker-jwt": "^2.5.3",
8990
"@types/react": "^18.2.22",

workers/svg_renderer/index.ts

Lines changed: 46 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -1,9 +1,13 @@
1+
import { Resvg, initWasm } from "@resvg/resvg-wasm";
12
import { Hono } from "hono";
23
import { QR } from "qr-svg";
34

45
import { createLogger } from "~/logging";
56
import { isValidUUID } from "~/schema/shared/helpers";
67

8+
// @ts-expect-error This import actually exists
9+
import resvgwasm from "./index_bg.wasm";
10+
711
const app = new Hono();
812

913
app.get("/qr/raw/:id", (c) => {
@@ -36,6 +40,48 @@ app.get("/qr/svg/:id", (c) => {
3640
return c.text(svg);
3741
});
3842

43+
app.get("/qr/png/:id", async (c) => {
44+
const logger = createLogger("qr-render-png");
45+
const uuid = c.req.param("id").trim().toLowerCase();
46+
47+
if (!isValidUUID(uuid)) {
48+
logger.error("Invalid id");
49+
throw new Error("Invalid id");
50+
}
51+
52+
try {
53+
await initWasm(resvgwasm as WebAssembly.Module);
54+
} catch (error) {
55+
logger.error("Resvg wasm not initialized");
56+
}
57+
58+
const svg = QR(uuid);
59+
60+
const resvg = new Resvg(svg, {
61+
background: "white",
62+
fitTo: {
63+
mode: "width",
64+
value: 1200,
65+
},
66+
font: {
67+
loadSystemFonts: false,
68+
},
69+
});
70+
71+
const pngData = resvg.render();
72+
const pngBuffer = pngData.asPng();
73+
74+
c.res.headers.set("Content-Type", "image/png");
75+
76+
return new Response(pngBuffer, {
77+
headers: {
78+
"Content-Type": "image/png",
79+
"Cache-Control": "public, immutable, no-transform, max-age=31536000",
80+
},
81+
status: 200,
82+
});
83+
});
84+
3985
app.get("/", (c) => {
4086
return c.json({
4187
message: "Greetings and salutations from the CommunityOS team",

workers/svg_renderer/index_bg.wasm

2.36 MB
Binary file not shown.

0 commit comments

Comments
 (0)