Skip to content

Commit cd04593

Browse files
committed
feat: add SVG as possible input format
Fix CorentinTh#1338
1 parent bac8c8d commit cd04593

File tree

5 files changed

+54
-4
lines changed

5 files changed

+54
-4
lines changed

package.json

Lines changed: 2 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -88,7 +88,9 @@
8888
"plausible-tracker": "^0.3.8",
8989
"qrcode": "^1.5.1",
9090
"randexp": "^0.5.3",
91+
"roboto-base64": "^0.1.2",
9192
"sql-formatter": "^13.0.0",
93+
"svg2png-wasm": "^1.4.1",
9294
"ua-parser-js": "^1.0.35",
9395
"ulid": "^2.3.0",
9496
"unicode-emoji-json": "^0.4.0",

pnpm-lock.yaml

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

public/svg2png_wasm_bg.wasm

1.9 MB
Binary file not shown.

src/tools/image-converter/image-converter.vue

Lines changed: 35 additions & 4 deletions
Original file line numberDiff line numberDiff line change
@@ -3,12 +3,24 @@ import { Base64 } from 'js-base64';
33
import type { MemoryImage } from 'image-in-browser';
44
import { decodeImage, encodeBmp, encodeGif, encodeIco, encodeJpg, encodePng, encodePvr, encodeTga, encodeTiff } from 'image-in-browser';
55
import { arrayBufferToWebP } from 'webp-converter-browser';
6+
import { createSvg2png, initialize } from 'svg2png-wasm';
7+
import { normal as robotoBase64 } from 'roboto-base64';
68
import { useDownloadFileFromBase64 } from '@/composable/downloadBase64';
79
import { useQueryParamOrStorage } from '@/composable/queryParams';
810
11+
function readAsText(file: File) {
12+
return new Promise<string>((resolve, reject) => {
13+
const reader = new FileReader();
14+
reader.readAsText(file);
15+
reader.onload = () => resolve(reader.result?.toString() ?? '');
16+
reader.onerror = error => reject(error);
17+
});
18+
}
19+
920
const status = ref<'idle' | 'done' | 'error' | 'processing'>('idle');
1021
const file = ref<File | null>(null);
1122
23+
const svgScale = ref(2);
1224
const base64OutputFile = ref('');
1325
const fileName = ref('');
1426
const fileExtension = ref('');
@@ -64,10 +76,12 @@ const outputFormatHasQuality = computed(() => {
6476
return outputFormat.value === 'jpg';
6577
});
6678
79+
const svgWasmLoaded = ref(false);
80+
6781
async function onFileUploaded(uploadedFile: File) {
6882
const outputFormatValue = outputFormat.value;
6983
file.value = uploadedFile;
70-
const fileBuffer = new Uint8Array(await uploadedFile.arrayBuffer());
84+
let fileBuffer = new Uint8Array(await uploadedFile.arrayBuffer());
7185
7286
fileName.value = `${uploadedFile.name}`;
7387
status.value = 'processing';
@@ -78,6 +92,17 @@ async function onFileUploaded(uploadedFile: File) {
7892
base64OutputFile.value = `data:image/webp;base64,${Base64.fromUint8Array(new Uint8Array(await encodedImage.arrayBuffer()))}`;
7993
}
8094
else {
95+
if (uploadedFile.type === 'image/svg+xml') {
96+
if (!svgWasmLoaded.value) {
97+
await initialize(fetch('/svg2png_wasm_bg.wasm'));
98+
svgWasmLoaded.value = true;
99+
}
100+
const svg2png = createSvg2png({
101+
fonts: [Base64.toUint8Array(robotoBase64)],
102+
});
103+
fileBuffer = await svg2png(await readAsText(uploadedFile), { scale: svgScale.value });
104+
svg2png.dispose();
105+
}
81106
const decodedImage = decodeImage({
82107
data: fileBuffer,
83108
});
@@ -122,9 +147,15 @@ async function onFileUploaded(uploadedFile: File) {
122147
placeholder="Select output format"
123148
mb-2
124149
/>
125-
<n-form-item v-if="outputFormatHasQuality" label="Output quality:" label-placement="left" mb-2>
126-
<n-input-number v-model:value="outputQuality" :max="100" :min="0" w-full />
127-
</n-form-item>
150+
151+
<div mb-2 flex justify-center>
152+
<n-form-item v-if="outputFormatHasQuality" label="Output quality:" label-placement="left">
153+
<n-input-number v-model:value="outputQuality" :max="100" :min="0" w-full />
154+
</n-form-item>
155+
<n-form-item label="SVG scaling:" label-placement="left">
156+
<n-input-number v-model:value="svgScale" :min="0" />
157+
</n-form-item>
158+
</div>
128159

129160
<div mt-3 flex justify-center>
130161
<c-alert v-if="status === 'error'" type="error">
Lines changed: 3 additions & 0 deletions
Original file line numberDiff line numberDiff line change
@@ -0,0 +1,3 @@
1+
declare module 'roboto-base64' {
2+
export const normal: string;
3+
}

0 commit comments

Comments
 (0)