Upload useExport.ts
Browse files- frontend/src/hooks/useExport.ts +58 -14
frontend/src/hooks/useExport.ts
CHANGED
@@ -13,6 +13,7 @@ import { type SvgPoints, toPoints } from '@/utils/svgPathParser'
|
|
13 |
import { encrypt } from '@/utils/crypto'
|
14 |
import { svg2Base64 } from '@/utils/svg2Base64'
|
15 |
import { renderElementToBase64, isCanvasRenderSupported, getElementDimensions } from '@/utils/canvasRenderer'
|
|
|
16 |
import message from '@/utils/message'
|
17 |
|
18 |
interface ExportImageConfig {
|
@@ -39,26 +40,69 @@ export default () => {
|
|
39 |
// 导出图片
|
40 |
const exportImage = (domRef: HTMLElement, format: string, quality: number, ignoreWebfont = true) => {
|
41 |
exporting.value = true
|
42 |
-
|
43 |
-
|
|
|
|
|
|
|
44 |
const foreignObjectSpans = domRef.querySelectorAll('foreignObject [xmlns]')
|
45 |
foreignObjectSpans.forEach(spanRef => spanRef.removeAttribute('xmlns'))
|
46 |
|
47 |
-
setTimeout(() => {
|
48 |
-
|
49 |
-
|
50 |
-
|
51 |
-
|
52 |
-
|
53 |
-
|
54 |
-
|
55 |
-
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
|
56 |
exporting.value = false
|
57 |
saveAs(dataUrl, `${title.value}.${format}`)
|
58 |
-
|
|
|
|
|
|
|
|
|
|
|
59 |
exporting.value = false
|
60 |
-
|
61 |
-
|
|
|
|
|
|
|
|
|
|
|
62 |
}, 200)
|
63 |
}
|
64 |
|
|
|
13 |
import { encrypt } from '@/utils/crypto'
|
14 |
import { svg2Base64 } from '@/utils/svg2Base64'
|
15 |
import { renderElementToBase64, isCanvasRenderSupported, getElementDimensions } from '@/utils/canvasRenderer'
|
16 |
+
import { renderWithHuggingfaceFix, isHuggingfaceEnvironment } from '@/utils/huggingfaceRenderer'
|
17 |
import message from '@/utils/message'
|
18 |
|
19 |
interface ExportImageConfig {
|
|
|
40 |
// 导出图片
|
41 |
const exportImage = (domRef: HTMLElement, format: string, quality: number, ignoreWebfont = true) => {
|
42 |
exporting.value = true
|
43 |
+
|
44 |
+
// 检查是否在Huggingface环境
|
45 |
+
const isHF = isHuggingfaceEnvironment()
|
46 |
+
console.log('exportImage: Environment check:', { isHuggingface: isHF, format })
|
47 |
+
|
48 |
const foreignObjectSpans = domRef.querySelectorAll('foreignObject [xmlns]')
|
49 |
foreignObjectSpans.forEach(spanRef => spanRef.removeAttribute('xmlns'))
|
50 |
|
51 |
+
setTimeout(async () => {
|
52 |
+
try {
|
53 |
+
let dataUrl: string
|
54 |
+
|
55 |
+
if (isHF) {
|
56 |
+
// Huggingface环境使用专用渲染器
|
57 |
+
console.log('exportImage: Using Huggingface renderer')
|
58 |
+
dataUrl = await renderWithHuggingfaceFix(domRef)
|
59 |
+
|
60 |
+
// 如果需要JPEG格式,转换PNG到JPEG
|
61 |
+
if (format === 'jpeg' && dataUrl.startsWith('data:image/png')) {
|
62 |
+
const canvas = document.createElement('canvas')
|
63 |
+
const ctx = canvas.getContext('2d')
|
64 |
+
const img = new Image()
|
65 |
+
|
66 |
+
await new Promise((resolve, reject) => {
|
67 |
+
img.onload = () => {
|
68 |
+
canvas.width = img.width
|
69 |
+
canvas.height = img.height
|
70 |
+
ctx?.drawImage(img, 0, 0)
|
71 |
+
dataUrl = canvas.toDataURL('image/jpeg', quality)
|
72 |
+
resolve(dataUrl)
|
73 |
+
}
|
74 |
+
img.onerror = reject
|
75 |
+
img.src = dataUrl
|
76 |
+
})
|
77 |
+
}
|
78 |
+
} else {
|
79 |
+
// 非Huggingface环境使用原有方法
|
80 |
+
const toImage = format === 'png' ? toPng : toJpeg
|
81 |
+
const config: ExportImageConfig = {
|
82 |
+
quality,
|
83 |
+
width: 1600,
|
84 |
+
}
|
85 |
+
|
86 |
+
if (ignoreWebfont) config.fontEmbedCSS = ''
|
87 |
+
dataUrl = await toImage(domRef, config)
|
88 |
+
}
|
89 |
+
|
90 |
exporting.value = false
|
91 |
saveAs(dataUrl, `${title.value}.${format}`)
|
92 |
+
|
93 |
+
if (isHF) {
|
94 |
+
message.success('图片导出成功(Huggingface优化版本)')
|
95 |
+
}
|
96 |
+
} catch (error) {
|
97 |
+
console.error('exportImage failed:', error)
|
98 |
exporting.value = false
|
99 |
+
|
100 |
+
if (isHF) {
|
101 |
+
message.error('图片导出失败,Huggingface环境可能存在兼容性问题')
|
102 |
+
} else {
|
103 |
+
message.error('导出图片失败')
|
104 |
+
}
|
105 |
+
}
|
106 |
}, 200)
|
107 |
}
|
108 |
|