@@ -3,12 +3,24 @@ import { Base64 } from 'js-base64';
3
3
import type { MemoryImage } from ' image-in-browser' ;
4
4
import { decodeImage , encodeBmp , encodeGif , encodeIco , encodeJpg , encodePng , encodePvr , encodeTga , encodeTiff } from ' image-in-browser' ;
5
5
import { arrayBufferToWebP } from ' webp-converter-browser' ;
6
+ import { createSvg2png , initialize } from ' svg2png-wasm' ;
7
+ import { normal as robotoBase64 } from ' roboto-base64' ;
6
8
import { useDownloadFileFromBase64 } from ' @/composable/downloadBase64' ;
7
9
import { useQueryParamOrStorage } from ' @/composable/queryParams' ;
8
10
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
+
9
20
const status = ref <' idle' | ' done' | ' error' | ' processing' >(' idle' );
10
21
const file = ref <File | null >(null );
11
22
23
+ const svgScale = ref (2 );
12
24
const base64OutputFile = ref (' ' );
13
25
const fileName = ref (' ' );
14
26
const fileExtension = ref (' ' );
@@ -64,10 +76,12 @@ const outputFormatHasQuality = computed(() => {
64
76
return outputFormat .value === ' jpg' ;
65
77
});
66
78
79
+ const svgWasmLoaded = ref (false );
80
+
67
81
async function onFileUploaded(uploadedFile : File ) {
68
82
const outputFormatValue = outputFormat .value ;
69
83
file .value = uploadedFile ;
70
- const fileBuffer = new Uint8Array (await uploadedFile .arrayBuffer ());
84
+ let fileBuffer = new Uint8Array (await uploadedFile .arrayBuffer ());
71
85
72
86
fileName .value = ` ${uploadedFile .name } ` ;
73
87
status .value = ' processing' ;
@@ -78,6 +92,17 @@ async function onFileUploaded(uploadedFile: File) {
78
92
base64OutputFile .value = ` data:image/webp;base64,${Base64 .fromUint8Array (new Uint8Array (await encodedImage .arrayBuffer ()))} ` ;
79
93
}
80
94
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
+ }
81
106
const decodedImage = decodeImage ({
82
107
data: fileBuffer ,
83
108
});
@@ -122,9 +147,15 @@ async function onFileUploaded(uploadedFile: File) {
122
147
placeholder =" Select output format"
123
148
mb-2
124
149
/>
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 >
128
159
129
160
<div mt-3 flex justify-center >
130
161
<c-alert v-if =" status === 'error'" type =" error" >
0 commit comments