xl-public-utils 1.0.4 → 1.0.5

This diff represents the content of publicly available package versions that have been released to one of the supported registries. The information contained in this diff is provided for informational purposes only and reflects changes between package versions as they appear in their respective public registries.
@@ -0,0 +1,285 @@
1
+ import vtkPolyData from "@kitware/vtk.js/Common/DataModel/PolyData";
2
+ import { mat4 } from "gl-matrix";
3
+ var FormatTypes = {
4
+ ASCII: 'ascii',
5
+ BINARY: 'binary'
6
+ };
7
+ var TextureCoordinatesName = {
8
+ UV: ['u', 'v'],
9
+ TEXTURE_UV: ['texture_u', 'texture_v']
10
+ };
11
+
12
+ var DEFAULT_VALUES = {
13
+ format: FormatTypes.ASCII,
14
+ dataByteOrder: 0,
15
+ headerComments: [],
16
+ textureFileName: '',
17
+ textureCoordinatesName: TextureCoordinatesName.UV,
18
+ withNormals: false,
19
+ withUVs: false,
20
+ withColors: false,
21
+ withIndices: true
22
+ }
23
+
24
+ var _writeHeader = function writeHeader(polyData, fileFormat, fileType, headerComments, textureFileName, textureCoordinatesName, vertexCount, faceListLength, withNormals, withUVs, withColors, withIndices) {
25
+ var isBinary = fileFormat !== FormatTypes.ASCII;
26
+ var format;
27
+
28
+ if (isBinary) {
29
+ format = fileType ? 'binary_little_endian' : 'binary_big_endian';
30
+ } else format = 'ascii';
31
+
32
+ headerComments.unshift('VTK.js generated PLY File');
33
+
34
+ if (textureFileName) {
35
+ headerComments.push("TextureFile ".concat(textureFileName));
36
+ }
37
+
38
+ var commentElements = headerComments.map(function (comment) {
39
+ return "comment ".concat(comment);
40
+ }).join('\n');
41
+ var header = ['ply', "format ".concat(format, " 1.0"), "".concat(commentElements), "element vertex ".concat(vertexCount), 'property float x', 'property float y', 'property float z']; // normals
42
+
43
+ if (withNormals) {
44
+ header.push('property float nx', 'property float ny', 'property float nz');
45
+ } // uvs
46
+
47
+
48
+ if (withUVs) {
49
+ header.push("property float ".concat(textureCoordinatesName[0]), "property float ".concat(textureCoordinatesName[1]));
50
+ } // colors
51
+
52
+
53
+ if (withColors) {
54
+ header.push('property uchar red', 'property uchar green', 'property uchar blue');
55
+ } // faces
56
+
57
+
58
+ if (withIndices) {
59
+ header.push("element face ".concat(faceListLength), 'property list uchar int vertex_indices');
60
+ }
61
+
62
+ header.push('end_header\n');
63
+ return header.join('\n');
64
+ };
65
+
66
+ var binaryWriter = function binaryWriter() {
67
+ var output;
68
+ var vOffset;
69
+ var fOffset;
70
+ var indexByteCount = 4;
71
+ var ft;
72
+ return {
73
+ init: function init(polyData) {},
74
+ writeHeader: function writeHeader(polyData, fileFormat, fileType, headerComments, textureFileName, textureCoordinatesName, numPts, numPolys, withNormals, withUVs, withColors, withIndices) {
75
+ var vertexCount = polyData.getPoints().getNumberOfPoints();
76
+ ft = fileType; // 1 byte shape descriptor
77
+ // 3 vertex indices at ${indexByteCount} bytes
78
+
79
+ var faceListLength = withIndices ? numPolys * (indexByteCount * 3 + 1) : 0; // 3 position values at 4 bytes
80
+ // 3 normal values at 4 bytes
81
+ // 3 color channels with 1 byte
82
+ // 2 uv values at 4 bytes
83
+
84
+ var vertexListLength = vertexCount * (4 * 3 + (withNormals ? 4 * 3 : 0) + (withUVs ? 4 * 2 : 0) + (withColors ? 3 : 0));
85
+
86
+ var header = _writeHeader(polyData, fileFormat, fileType, headerComments, textureFileName, textureCoordinatesName, numPts, numPolys, withNormals, withUVs, withColors, withIndices);
87
+
88
+ var headerBin = new TextEncoder().encode(header);
89
+ output = new DataView(new ArrayBuffer(headerBin.length + vertexListLength + faceListLength));
90
+ new Uint8Array(output.buffer).set(headerBin, 0);
91
+ vOffset = headerBin.length;
92
+ fOffset = vOffset + vertexListLength;
93
+ },
94
+ writeVertice: function writeVertice(x, y, z, nx, ny, nz, u, v, r, g, b) {
95
+ // xyz
96
+ output.setFloat32(vOffset, x, ft);
97
+ vOffset += 4;
98
+ output.setFloat32(vOffset, y, ft);
99
+ vOffset += 4;
100
+ output.setFloat32(vOffset, z, ft);
101
+ vOffset += 4; // nxnynz
102
+
103
+ if (nx !== null && ny !== null && nz !== null) {
104
+ output.setFloat32(vOffset, nx, ft);
105
+ vOffset += 4;
106
+ output.setFloat32(vOffset, ny, ft);
107
+ vOffset += 4;
108
+ output.setFloat32(vOffset, nz, ft);
109
+ vOffset += 4;
110
+ } // uv
111
+
112
+
113
+ if (u !== null && v !== null) {
114
+ output.setFloat32(vOffset, u, ft);
115
+ vOffset += 4;
116
+ output.setFloat32(vOffset, v, ft);
117
+ vOffset += 4;
118
+ } // rgb
119
+
120
+
121
+ if (r !== null && g !== null && b !== null) {
122
+ output.setUint8(vOffset, r);
123
+ vOffset += 1;
124
+ output.setUint8(vOffset, g);
125
+ vOffset += 1;
126
+ output.setUint8(vOffset, b);
127
+ vOffset += 1;
128
+ }
129
+ },
130
+ writeFace: function writeFace(n, x, y, z) {
131
+ output.setUint8(fOffset, n);
132
+ fOffset += 1;
133
+ output.setUint32(fOffset, x, ft);
134
+ fOffset += indexByteCount;
135
+ output.setUint32(fOffset, y, ft);
136
+ fOffset += indexByteCount;
137
+ output.setUint32(fOffset, z, ft);
138
+ fOffset += indexByteCount;
139
+ },
140
+ writeFooter: function writeFooter(polyData) {},
141
+ getOutputData: function getOutputData() {
142
+ return output;
143
+ }
144
+ };
145
+ };
146
+
147
+ var asciiWriter = function asciiWriter() {
148
+ var fileContent = '';
149
+ return {
150
+ init: function init(polyData) {},
151
+ writeHeader: function writeHeader(polyData, fileFormat, fileType, headerComments, textureFileName, textureCoordinatesName, numPts, numPolys, withNormals, withUVs, withColors, withIndices) {
152
+ fileContent += _writeHeader(polyData, fileFormat, fileType, headerComments, textureFileName, textureCoordinatesName, numPts, numPolys, withNormals, withUVs, withColors, withIndices);
153
+ },
154
+ writeVertice: function writeVertice(x, y, z, nx, ny, nz, u, v, r, g, b) {
155
+ fileContent += "".concat(x, " ").concat(y, " ").concat(z);
156
+
157
+ if (nx !== null && ny !== null && nz !== null) {
158
+ fileContent += " ".concat(nx, " ").concat(ny, " ").concat(nz);
159
+ }
160
+
161
+ if (u !== null && v !== null) {
162
+ fileContent += " ".concat(u, " ").concat(v);
163
+ }
164
+
165
+ if (r !== null && g !== null && b !== null) {
166
+ fileContent += " ".concat(r, " ").concat(g, " ").concat(b);
167
+ }
168
+
169
+ fileContent += '\n';
170
+ },
171
+ writeFace: function writeFace(n, x, y, z) {
172
+ fileContent += "".concat(n, " ").concat(x, " ").concat(y, " ").concat(z, "\n");
173
+ },
174
+ writeFooter: function writeFooter(polyData) {},
175
+ getOutputData: function getOutputData() {
176
+ return fileContent;
177
+ }
178
+ };
179
+ };
180
+
181
+ /**
182
+ * 将polyData转换为ply文件
183
+ * @param {vtkPolyData} polyData 需要导出的polydata
184
+ * @param {'ascii' | 'binary'} format 导出文件格式
185
+ * @param {0 | 1} dataByteOrder=0 字节序,默认为0, 0为大端模式, 1小端模式
186
+ * @param {string[]} headerComments=[] 文件头描述
187
+ * @param {string} textureFileName='' header描述文件名
188
+ * @param {['u', 'v']} textureCoordinatesName=['u', 'v'] header添加u和v
189
+ * @param {boolean} withNormals=false 是否需要法向量
190
+ * @param {boolean} withUVs=false 是否需要UV
191
+ * @param {boolean} withColors=false 是否需要Colors
192
+ * @param {boolean} withColors=true 面使用点索引
193
+ * @returns {string | DataView} 返回文件内容
194
+ */
195
+ export function writePLY(polyData, format, dataByteOrder = DEFAULT_VALUES.dataByteOrder, headerComments = DEFAULT_VALUES.headerComments, textureFileName = DEFAULT_VALUES.textureFileName, textureCoordinatesName = DEFAULT_VALUES.textureCoordinatesName, withNormals = DEFAULT_VALUES.withNormals, withUVs = DEFAULT_VALUES.withUVs, withColors = DEFAULT_VALUES.withColors, withIndices = DEFAULT_VALUES.withIndices) {
196
+ var inPts = polyData.getPoints();
197
+ var polys = polyData.getPolys();
198
+
199
+ if (inPts === null || polys === null) {
200
+ console.error('输入错误!')
201
+ }
202
+
203
+ var writer = null;
204
+
205
+ if (format === 'binary') {
206
+ writer = binaryWriter();
207
+ } else if (format === 'ascii') {
208
+ writer = asciiWriter();
209
+ } else {
210
+ console.error('Invalid type format');
211
+ }
212
+
213
+ var tCoordsName = textureCoordinatesName;
214
+
215
+ if (typeof textureCoordinatesName === 'undefined') {
216
+ console.log('Invalid TextureCoordinatesName value, fallback to default uv values');
217
+ tCoordsName = TextureCoordinatesName.UV;
218
+ }
219
+
220
+ writer.init(polyData);
221
+ var numPts = inPts.getNumberOfPoints();
222
+ var numPolys = polys.getNumberOfCells(); // textureCoords / uvs
223
+
224
+ var textureCoords = polyData.getPointData().getTCoords(); // eslint-disable-next-line no-param-reassign
225
+
226
+ // withUVs = !(textureCoords === null); // scalars / colors
227
+
228
+ var scalars = polyData.getPointData().getScalars(); // eslint-disable-next-line no-param-reassign
229
+
230
+ withColors = !(scalars === null);
231
+ var fileType = dataByteOrder ? 0 : 1;
232
+ writer.writeHeader(polyData, format, fileType, headerComments, textureFileName, tCoordsName, numPts, numPolys, withNormals, withUVs, withColors, withIndices);
233
+ var normals = polyData.getPointData().getNormals(); // points / vertices
234
+
235
+ for (var i = 0; i < numPts; i++) {
236
+ // eslint-disable-next-line prefer-const
237
+ var p = inPts.getPoint(i);
238
+ // divide by 1 to remove trailing zeros
239
+
240
+
241
+ var x = p[0].toFixed(8);
242
+ var y = p[1].toFixed(8);
243
+ var z = p[2].toFixed(8); // normals
244
+
245
+ var nx = null;
246
+ var ny = null;
247
+ var nz = null; // uvs
248
+
249
+ var u = null;
250
+ var v = null; // colors
251
+
252
+ var r = null;
253
+ var g = null;
254
+ var b = null;
255
+
256
+ // if (textureCoords) {
257
+ // u = textureCoords.getData()[i * 2];
258
+ // v = textureCoords.getData()[i * 2 + 1];
259
+ // }
260
+
261
+ if (scalars) {
262
+ r = scalars.getData()[i * 3];
263
+ g = scalars.getData()[i * 3 + 1];
264
+ b = scalars.getData()[i * 3 + 2];
265
+ }
266
+
267
+ if (normals) {
268
+ nx = normals.getData()[i * 2];
269
+ ny = normals.getData()[i * 2 + 1];
270
+ nz = normals.getData()[i * 2 + 2];
271
+ }
272
+
273
+ writer.writeVertice(x, y, z, nx, ny, nz, u, v, r, g, b);
274
+ } // polys / indices
275
+
276
+
277
+ var pd = polys.getData();
278
+
279
+ for (var _i = 0, l = pd.length; _i < l; _i += 4) {
280
+ writer.writeFace(pd[_i + 0], pd[_i + 1], pd[_i + 2], pd[_i + 3]);
281
+ }
282
+
283
+ writer.writeFooter(polyData);
284
+ return writer.getOutputData();
285
+ }
@@ -0,0 +1,222 @@
1
+ import vtkPolyData from '@kitware/vtk.js/Common/DataModel/PolyData';
2
+ import { vec3 } from 'gl-matrix';
3
+
4
+ /**
5
+ * 离散stl重复的点并格式化输出
6
+ * @param {vtkPolyData} polydata 网格
7
+ * @returns 离散化之后的PolyData
8
+ */
9
+ var getResult = function (polydata) {
10
+ var points = [...polydata.getPoints().getData()];
11
+ // 离散化
12
+ dispersedPoints2Stl(points)
13
+ var vAr = new Float32Array(points);
14
+ var iAr = new Uint32Array([...polydata.getPolys().getData()]);
15
+ const nbTriangles = iAr.length / 4;
16
+ const { set, sub, cross, normalize, create} = vec3
17
+ var v1 = create();
18
+ var v2 = create();
19
+ var v3 = create();
20
+ var nAr = new Float32Array(nbTriangles * 3);
21
+ for (var i = 0; i < nbTriangles; ++i) {
22
+ var id = i * 4;
23
+ var i1 = iAr[id + 1] * 3;
24
+ var i2 = iAr[id + 2] * 3;
25
+ var i3 = iAr[id + 3] * 3;
26
+ set(v1, vAr[i1], vAr[i1 + 1], vAr[i1 + 2]);
27
+ set(v2, vAr[i2], vAr[i2 + 1], vAr[i2 + 2]);
28
+ set(v3, vAr[i3], vAr[i3 + 1], vAr[i3 + 2]);
29
+
30
+ sub(v2, v2, v1); // v2 = v2 - v1
31
+ sub(v3, v3, v2); // v3 = v3 - v1
32
+ cross(v1, v2, v3); // v1 = v2 ^ v3
33
+ normalize(v1, v1);
34
+
35
+ nAr[id] = v1[0];
36
+ nAr[id + 1] = v1[1];
37
+ nAr[id + 2] = v1[2];
38
+ }
39
+
40
+ return {
41
+ nbTriangles,
42
+ vertices: vAr,
43
+ triangles: iAr,
44
+ faceNormals: nAr,
45
+ nbVertices: vAr.length / 3,
46
+ };
47
+ };
48
+
49
+ /**
50
+ * 获取网格的AsciiSTL文件类容
51
+ * @param {vtkPolyData} polydata 网格
52
+ * @returns {string} 网格的asciiSTL文件内容
53
+ */
54
+ const exportAsciiSTL = function (polydata) {
55
+ var res = getResult(polydata);
56
+ var nbTriangles = res.nbTriangles;
57
+ var vAr = res.vertices;
58
+ var iAr = res.triangles;
59
+ var fnAr = res.faceNormals;
60
+
61
+ var data = 'solid mesh\n';
62
+ for (var i = 0; i < nbTriangles; ++i) {
63
+ var id = i * 3;
64
+ const fid = i * 4;
65
+ data += ' facet normal ' + fnAr[id] + ' ' + fnAr[id + 1] + ' ' + fnAr[id + 2] + '\n';
66
+ data += ' outer loop\n';
67
+ var iv1 = iAr[fid + 1] * 3;
68
+ var iv2 = iAr[fid + 2] * 3;
69
+ var iv3 = iAr[fid + 3] * 3;
70
+ data += ' vertex ' + vAr[iv1] + ' ' + vAr[iv1 + 1] + ' ' + vAr[iv1 + 2] + '\n';
71
+ data += ' vertex ' + vAr[iv2] + ' ' + vAr[iv2 + 1] + ' ' + vAr[iv2 + 2] + '\n';
72
+ data += ' vertex ' + vAr[iv3] + ' ' + vAr[iv3 + 1] + ' ' + vAr[iv3 + 2] + '\n';
73
+ data += ' endloop\n';
74
+ data += ' endfacet\n';
75
+ }
76
+ data += 'endsolid mesh\n';
77
+ return new Blob([data]);
78
+ };
79
+
80
+ /**
81
+ * 获取网格的BinarySTL文件类容
82
+ * @param {vtkPolyData} polydata 网格
83
+ * @param {boolean} colorMagic=false 颜色
84
+ * @returns {Blob} 网格的BinarySTL文件内容
85
+ */
86
+ const exportBinarySTL = function (polydata, colorMagic = false) {
87
+ var res = getResult(polydata);
88
+ var nbTriangles = res.nbTriangles;
89
+ var vAr = res.vertices;
90
+ // var cAr = res.colors;
91
+ var iAr = res.triangles;
92
+ // var fnAr = res.faceNormals;
93
+ var i, k;
94
+
95
+ var data = new Uint8Array(84 + nbTriangles * 50);
96
+ if (colorMagic) {
97
+ // COLOR=255,255,255,255
98
+ var hdr = [67, 79, 76, 79, 82, 61, 255, 255, 255, 255];
99
+ for (i = 0; i < hdr.length; ++i) {
100
+ data[i] = hdr[i];
101
+ }
102
+ }
103
+
104
+ (new DataView(data.buffer)).setUint32(80, nbTriangles, true);
105
+ // var verBuffer = new Uint8Array((vAr as any).buffer);
106
+ // var norBuffer = new Uint8Array(fnAr.buffer);
107
+ var offset = 84;
108
+ var inc = 0;
109
+
110
+ // var colorActivate = colorMagic ? 0 : (1 << 15);
111
+
112
+ const dataView = new DataView(data.buffer)
113
+ // var mulc = 31 / 3;
114
+ for (i = 0; i < nbTriangles; ++i) {
115
+ k = i * 12;
116
+ // for (inc = 0; inc < 12; ++inc) {
117
+ // offset++
118
+ // // data[offset++] = norBuffer[k++];
119
+ // }
120
+ offset += 12
121
+ k = i * 3;
122
+ const fid = i * 4;
123
+ var iv1 = iAr[fid + 1] * 3;
124
+ var iv2 = iAr[fid + 2] * 3;
125
+ var iv3 = iAr[fid + 3] * 3;
126
+ var id1 = iv1 * 4;
127
+ // for (inc = 0; inc < 12; ++inc) {
128
+ // data[offset++] = verBuffer[id1++];
129
+ // }
130
+ // var id2 = iv2 * 4;
131
+ // for (inc = 0; inc < 12; ++inc) {
132
+ // data[offset++] = verBuffer[id2++];
133
+ // }
134
+ // var id3 = iv3 * 4;
135
+ // for (inc = 0; inc < 12; ++inc) {
136
+ // data[offset++] = verBuffer[id3++];
137
+ // }
138
+ for(inc =0; inc < 3; ++inc){
139
+ dataView.setFloat32(offset, vAr[iv1 + inc], true);
140
+ offset = offset + 4;
141
+ }
142
+ for(inc =0; inc < 3; ++inc){
143
+ dataView.setFloat32(offset, vAr[iv2 + inc], true);
144
+ offset = offset + 4;
145
+ }
146
+ for(inc =0; inc < 3; ++inc){
147
+ dataView.setFloat32(offset, vAr[iv3 + inc], true);
148
+ offset = offset + 4;
149
+ }
150
+
151
+ offset++;
152
+ offset++
153
+
154
+ }
155
+ return new Blob([data]);
156
+ };
157
+ /**
158
+ * 对数值进行处理,保留几位小数
159
+ * @param {number} num 数值
160
+ * @param {number} fix=4 保留几位小数
161
+ * @returns 格式化之后的数值
162
+ */
163
+ function getFixed4(num, fix = 4) {
164
+ return +num.toFixed(fix)
165
+ }
166
+ /**
167
+ * 根据点生成key
168
+ * @param {number[]} point 三位点
169
+ * @returns 根据点xyz生成key,取小数位前4位置
170
+ */
171
+ function getPointKey(point) {
172
+ return `${getFixed4(point[0])},${getFixed4(point[1])},${getFixed4(point[2])}`;
173
+ }
174
+ /**
175
+ * 返回噪点随机数
176
+ * @returns {number} 早点随机数
177
+ */
178
+ function randNum() {
179
+ return (
180
+ (Math.random() > 0.5 ? 1 : -1) * (Math.random() * (1e-4 - 1e-5)) + 1e-5
181
+ );
182
+ }
183
+ /**
184
+ * 导出stl模型的时候 需要离散点 防止被认为是同一个点 精度到e-7就够了
185
+ * @param {number[]} points 网格点
186
+ */
187
+ export function dispersedPoints2Stl(points) {
188
+ let pointMap = new Map();
189
+ for (let i = 0; i < points.length; i += 3) {
190
+ let transformPoint = [points[i], points[i + 1], points[i + 2]];
191
+ const key = getPointKey(transformPoint);
192
+ if (pointMap.has(key)) {
193
+ let randPoint = [
194
+ transformPoint[0] + randNum(),
195
+ transformPoint[1] + randNum(),
196
+ transformPoint[2] + randNum(),
197
+ ];
198
+ let randKey = getPointKey(randPoint);
199
+ let attemptTimes = 0;
200
+ while (pointMap.has(randKey) && attemptTimes < 1000) {
201
+ randPoint = [
202
+ transformPoint[0] + randNum(),
203
+ transformPoint[1] + randNum(),
204
+ transformPoint[2] + randNum(),
205
+ ];
206
+ randKey = getPointKey(randPoint);
207
+ attemptTimes++;
208
+ }
209
+ points[i] = randPoint[0];
210
+ points[i + 1] = randPoint[1];
211
+ points[i + 2] = randPoint[2];
212
+ pointMap.set(randKey, true);
213
+ // import.meta.env.DEV && console.log('重复点', [points[i], points[i + 1], points[i + 2]])
214
+ } else {
215
+ pointMap.set(key, true);
216
+ }
217
+ }
218
+ }
219
+ export {
220
+ exportBinarySTL,
221
+ exportAsciiSTL,
222
+ }
package/src/qrcode.mjs CHANGED
@@ -2,22 +2,22 @@ import { qrcode, datamatrix} from './bwip-js.mjs';
2
2
 
3
3
  /**
4
4
  * @typedef {Object} QrCodeOptions
5
- * @property {'qrcode' | 'dataMatrix'} [bcid='qrcode'] - 二维码类型,具体支持请查看文档
6
- * @property {number} [width=1056] - 最终图片宽度
7
- * @property {number} [height=342] - 最终图片高度
8
- * @property {number} [qrcodeW=300] - 二维码宽度
9
- * @property {number} [qrcodeH=300] - 二维码高度
10
- * @property {boolean} [addText=true] - 是否在右侧添加文字
11
- * @property {number} [top=10] - 顶部距离
12
- * @property {number} [left=10] - 左侧距离
13
- * @property {number} [lineHeight=1] - 文字行高,换行后下一行文字的y位置计算为fontSize * lineHeight
14
- * @property {number} [fontSize=60] - 文字大小
15
- * @property {string} [fontFamily='黑体'] - 字体类型
16
- * @property {string} [bgColor='#fff'] - 背景颜色
17
- * @property {number} [textLeftMargin=20] - 文字距离二维码间隔
18
- * @property {boolean} [fontWeight=700] - 字体加粗
19
- * @property {string} [textColor='#000'] - 字体颜色
20
- * @property {string} [textContent] - 右侧文字内容
5
+ * @property {'qrcode' | 'dataMatrix'} bcid='qrcode' - 二维码类型,具体支持请查看文档
6
+ * @property {number} width=1056 - 最终图片宽度
7
+ * @property {number} height=342 - 最终图片高度
8
+ * @property {number} qrcodeW=300 - 二维码宽度
9
+ * @property {number} qrcodeH=300 - 二维码高度
10
+ * @property {boolean} addText=true - 是否在右侧添加文字
11
+ * @property {number} top=10 - 顶部距离
12
+ * @property {number} left=10 - 左侧距离
13
+ * @property {number} lineHeight=1 - 文字行高,换行后下一行文字的y位置计算为fontSize * lineHeight
14
+ * @property {number} fontSize=60 - 文字大小
15
+ * @property {string} fontFamily='黑体' - 字体类型
16
+ * @property {string} bgColor='#fff' - 背景颜色
17
+ * @property {number} textLeftMargin=20 - 文字距离二维码间隔
18
+ * @property {boolean} fontWeight=700 - 字体加粗
19
+ * @property {string} textColor='#000' - 字体颜色
20
+ * @property {string} textContent - 右侧文字内容
21
21
  */
22
22
 
23
23
  /**
package/src/utils.mjs CHANGED
@@ -29,4 +29,46 @@ export function getRatio() {
29
29
  * Alias for {@link getRatio}
30
30
  * @function
31
31
  */
32
- export const detectZoom = getRatio;
32
+ export const detectZoom = getRatio;
33
+
34
+ /**
35
+ * 将Base64转换为ArrayBuffer
36
+ * @param {string} base64String
37
+ * @returns {ArrayBuffer} base64的ArrayBuffer
38
+ */
39
+
40
+ export function base64ToArrayBuffer(base64String) {
41
+ const binary_string = window.atob(base64String);
42
+ const len = binary_string.length;
43
+ const bytes = new Uint8Array(len);
44
+ for (var i = 0; i < len; i++) {
45
+ bytes[i] = binary_string.charCodeAt(i);
46
+ }
47
+ return bytes.buffer
48
+ }
49
+
50
+ /**
51
+ * 将Int8Array转换为Base64格式的字符串
52
+ * @param {Int8Array} int8
53
+ * @returns {string} base64格式的字符串
54
+ */
55
+ export function int8ArrayToBase64(int8) {
56
+ const data = new Uint8Array(int8)
57
+ let base64String = '';
58
+ for (let i = 0; i < data.length; i++) {
59
+ base64String += String.fromCharCode(data[i])
60
+ }
61
+ return window.btoa(base64String)
62
+ }
63
+
64
+
65
+ /**
66
+ * 将ArrayBuffer转换为Base64格式的字符串
67
+ * @param {ArrayBuffer} outputBuffer
68
+ * @returns {string} base64格式的字符串
69
+ */
70
+ export function arrayBufferToBase64(outputBuffer) {
71
+ const outputData = new Int8Array(outputBuffer);
72
+
73
+ return int8ArrayToBase64(outputData)
74
+ }