CatPtain commited on
Commit
8ba8019
·
verified ·
1 Parent(s): 74a3356

Upload 3 files

Browse files
Files changed (1) hide show
  1. frontend/src/utils/svg2Base64.ts +126 -1
frontend/src/utils/svg2Base64.ts CHANGED
@@ -47,15 +47,35 @@ const encode = (input: string) => {
47
  return output
48
  }
49
 
 
 
 
 
 
 
 
 
 
 
50
  export const svg2Base64 = (element: Element) => {
 
 
 
51
  try {
52
  console.log('svg2Base64: Starting conversion for element:', {
53
  tagName: element.tagName,
54
  className: element.className,
55
  id: element.id,
56
- hasChildren: element.children.length > 0
 
57
  });
58
 
 
 
 
 
 
 
59
  // 克隆元素以避免修改原始DOM
60
  const clonedElement = element.cloneNode(true) as Element;
61
  console.log('svg2Base64: Element cloned successfully');
@@ -238,4 +258,109 @@ export const svg2Base64 = (element: Element) => {
238
  console.error('svg2Base64: All fallback strategies failed');
239
  throw new Error(`SVG to Base64 conversion failed: ${error}`);
240
  }
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
 
241
  }
 
47
  return output
48
  }
49
 
50
+ // 导入Huggingface环境检测
51
+ const isHuggingfaceEnvironment = (): boolean => {
52
+ return (
53
+ typeof window !== 'undefined' &&
54
+ (window.location.hostname.includes('hf.space') ||
55
+ window.location.hostname.includes('huggingface.co') ||
56
+ process.env.NODE_ENV === 'production')
57
+ );
58
+ };
59
+
60
  export const svg2Base64 = (element: Element) => {
61
+ // 检查是否在Huggingface环境
62
+ const isHF = isHuggingfaceEnvironment();
63
+
64
  try {
65
  console.log('svg2Base64: Starting conversion for element:', {
66
  tagName: element.tagName,
67
  className: element.className,
68
  id: element.id,
69
+ hasChildren: element.children.length > 0,
70
+ isHuggingfaceEnvironment: isHF
71
  });
72
 
73
+ // Huggingface环境使用简化的处理方式
74
+ if (isHF) {
75
+ console.log('svg2Base64: Using Huggingface optimized processing');
76
+ return huggingfaceOptimizedSvg2Base64(element);
77
+ }
78
+
79
  // 克隆元素以避免修改原始DOM
80
  const clonedElement = element.cloneNode(true) as Element;
81
  console.log('svg2Base64: Element cloned successfully');
 
258
  console.error('svg2Base64: All fallback strategies failed');
259
  throw new Error(`SVG to Base64 conversion failed: ${error}`);
260
  }
261
+ }
262
+
263
+ /**
264
+ * Huggingface环境优化的SVG转Base64函数
265
+ * 使用更简单、更兼容的方法
266
+ */
267
+ const huggingfaceOptimizedSvg2Base64 = (element: Element): string => {
268
+ try {
269
+ console.log('huggingfaceOptimizedSvg2Base64: Starting optimized conversion');
270
+
271
+ // 克隆元素
272
+ const clonedElement = element.cloneNode(true) as Element;
273
+
274
+ // 确保是SVG元素
275
+ if (clonedElement.tagName.toLowerCase() === 'svg') {
276
+ const svgElement = clonedElement as SVGElement;
277
+
278
+ // 设置基本属性
279
+ svgElement.setAttribute('xmlns', 'http://www.w3.org/2000/svg');
280
+
281
+ // 获取尺寸
282
+ const rect = element.getBoundingClientRect();
283
+ const width = rect.width || 100;
284
+ const height = rect.height || 100;
285
+
286
+ // 设置明确的尺寸
287
+ svgElement.setAttribute('width', width.toString());
288
+ svgElement.setAttribute('height', height.toString());
289
+ svgElement.setAttribute('viewBox', `0 0 ${width} ${height}`);
290
+
291
+ // 移除可能导致问题的属性
292
+ const removeProblematicAttrs = (elem: Element) => {
293
+ const problematicAttrs = ['vector-effect', 'xmlns:xlink'];
294
+ problematicAttrs.forEach(attr => {
295
+ if (elem.hasAttribute(attr)) {
296
+ elem.removeAttribute(attr);
297
+ }
298
+ });
299
+
300
+ // 递归处理子元素
301
+ Array.from(elem.children).forEach(child => {
302
+ removeProblematicAttrs(child);
303
+ });
304
+ };
305
+
306
+ removeProblematicAttrs(svgElement);
307
+
308
+ // 简化序列化
309
+ let svgString = svgElement.outerHTML;
310
+
311
+ // 基本清理
312
+ svgString = svgString.replace(/vector-effect="[^"]*"/g, '');
313
+ svgString = svgString.replace(/xmlns:xlink="[^"]*"/g, '');
314
+
315
+ // 确保命名空间正确
316
+ if (!svgString.includes('xmlns="http://www.w3.org/2000/svg"')) {
317
+ svgString = svgString.replace('<svg', '<svg xmlns="http://www.w3.org/2000/svg"');
318
+ }
319
+
320
+ console.log('huggingfaceOptimizedSvg2Base64: SVG string prepared:', {
321
+ length: svgString.length,
322
+ hasNamespace: svgString.includes('xmlns="http://www.w3.org/2000/svg"'),
323
+ preview: svgString.substring(0, 150) + '...'
324
+ });
325
+
326
+ // 使用btoa进行编码(更兼容)
327
+ const base64 = btoa(unescape(encodeURIComponent(svgString)));
328
+ const result = PREFIX + base64;
329
+
330
+ console.log('huggingfaceOptimizedSvg2Base64: Conversion successful, result length:', result.length);
331
+ return result;
332
+ }
333
+
334
+ // 非SVG元素的处理
335
+ console.warn('huggingfaceOptimizedSvg2Base64: Element is not SVG, using fallback');
336
+ const rect = element.getBoundingClientRect();
337
+ const width = rect.width || 100;
338
+ const height = rect.height || 100;
339
+
340
+ const fallbackSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
341
+ <foreignObject width="100%" height="100%">
342
+ <div xmlns="http://www.w3.org/1999/xhtml">${element.innerHTML}</div>
343
+ </foreignObject>
344
+ </svg>`;
345
+
346
+ const base64 = btoa(unescape(encodeURIComponent(fallbackSvg)));
347
+ return PREFIX + base64;
348
+
349
+ } catch (error) {
350
+ console.error('huggingfaceOptimizedSvg2Base64: Conversion failed:', error);
351
+
352
+ // 最终备选方案:创建简单的占位符SVG
353
+ const rect = element.getBoundingClientRect();
354
+ const width = rect.width || 100;
355
+ const height = rect.height || 100;
356
+
357
+ const placeholderSvg = `<svg xmlns="http://www.w3.org/2000/svg" width="${width}" height="${height}" viewBox="0 0 ${width} ${height}">
358
+ <rect width="100%" height="100%" fill="#f5f5f5" stroke="#ddd" stroke-width="1"/>
359
+ <text x="50%" y="50%" text-anchor="middle" dy="0.3em" font-family="Arial, sans-serif" font-size="14" fill="#999">SVG</text>
360
+ </svg>`;
361
+
362
+ const base64 = btoa(unescape(encodeURIComponent(placeholderSvg)));
363
+ console.log('huggingfaceOptimizedSvg2Base64: Using placeholder SVG');
364
+ return PREFIX + base64;
365
+ }
366
  }