You cannot select more than 25 topics Topics must start with a letter or number, can include dashes ('-') and can be up to 35 characters long.

130 lines
3.6 KiB
JavaScript

This file contains ambiguous Unicode characters!

This file contains ambiguous Unicode characters that may be confused with others in your current locale. If your use case is intentional and legitimate, you can safely ignore this warning. Use the Escape button to highlight these characters.

export const normalizeBase64Pure = (input) => {
let text = String(input ?? '').trim().replace(/\s/g, '')
if (!text) return ''
if (/^data:image\/[\w+.-]+;base64,/i.test(text)) {
text = text.replace(/^data:image\/[\w+.-]+;base64,/i, '')
}
return text
}
/** 补齐 padding并兼容 URL-safe Base64 */
export const fixBase64ForDecode = (pure) => {
let text = String(pure ?? '').replace(/-/g, '+').replace(/_/g, '/')
const mod = text.length % 4
if (mod === 2) text += '=='
else if (mod === 3) text += '='
return text
}
export const getMimeTypeFromBase64 = (pure) => {
if (pure.startsWith('iVBORw0KGgo')) return 'image/png'
return 'image/jpeg'
}
export const extractImageBase64FromResponse = (result) => {
if (result === undefined || result === null) return ''
if (typeof result === 'string') return result
if (result.imageBase64) return result.imageBase64
if (result.data !== undefined && result.data !== null) {
return extractImageBase64FromResponse(result.data)
}
return ''
}
export const isWebPlatform = () => {
if (typeof window === 'undefined' || typeof document === 'undefined') {
return false
}
try {
const sys = uni.getSystemInfoSync()
return sys.uniPlatform === 'web' || sys.uniPlatform === 'h5'
} catch {
return true
}
}
const decodeBase64ToBytes = (pure) => {
const normalized = fixBase64ForDecode(pure)
const binary = atob(normalized)
const bytes = new Uint8Array(binary.length)
for (let i = 0; i < binary.length; i++) {
bytes[i] = binary.charCodeAt(i)
}
return bytes
}
const createBlobUrlFromBase64 = (pure, mime) => {
const bytes = decodeBase64ToBytes(pure)
const blob = new Blob([bytes], { type: mime })
const blobUrl = URL.createObjectURL(blob)
return {
src: blobUrl,
revoke: () => URL.revokeObjectURL(blobUrl),
}
}
const createDataUrlFromBase64 = (pure, mime) => {
const normalized = fixBase64ForDecode(pure)
return {
src: `data:${mime};base64,${normalized}`,
revoke: null,
}
}
const tryWebDisplay = (pure, mime, resolve) => {
if (typeof window !== 'undefined' && typeof atob === 'function') {
try {
const blobResult = createBlobUrlFromBase64(pure, mime)
console.log('[face-image] 使用 Blob URL 展示')
resolve(blobResult)
return
} catch (error) {
console.log('[face-image] Blob URL 创建失败,回退 dataUrl', error)
}
}
console.log('[face-image] 使用 dataUrl 展示')
resolve(createDataUrlFromBase64(pure, mime))
}
/**
* 将 Base64 转为可在页面中展示的图片地址
*/
export const loadFaceImageDisplaySrc = (base64Raw) => {
return new Promise((resolve, reject) => {
const pure = normalizeBase64Pure(base64Raw)
if (!pure) {
reject(new Error('图片 Base64 为空'))
return
}
const mime = getMimeTypeFromBase64(pure)
console.log('[face-image] base64 前缀:', pure.slice(0, 24), 'mime:', mime)
if (isWebPlatform()) {
tryWebDisplay(pure, mime, resolve)
return
}
if (typeof uni.base64ToTempFilePath === 'function') {
uni.base64ToTempFilePath({
base64Data: fixBase64ForDecode(pure),
extension: mime === 'image/png' ? 'png' : 'jpg',
success: (res) => {
console.log('[face-image] 使用临时文件展示:', res.tempFilePath)
resolve({
src: res.tempFilePath,
revoke: null,
})
},
fail: (err) => {
console.log('[face-image] base64ToTempFilePath 失败', err)
tryWebDisplay(pure, mime, resolve)
},
})
return
}
tryWebDisplay(pure, mime, resolve)
})
}