/** * 在照片左下角叠加水印文字 * @param {string} imagePath - 原始图片路径 * @param {string} text - 水印文字(如 "2025/06/15 12:00 张三") * @returns {Promise} 带水印的临时文件路径(H5 返回 base64 dataURL) */ export function addWatermark(imagePath, text) { return new Promise((resolve, reject) => { // #ifdef APP-PLUS uni.getImageInfo({ src: imagePath, success(imgInfo) { const width = imgInfo.width const height = imgInfo.height const bitmap = new plus.nativeObj.Bitmap('watermark') bitmap.load(imagePath, () => { const canvas = new plus.nativeObj.View('watermarkView', { left: '0px', top: '0px', width: width + 'px', height: height + 'px' }) canvas.drawBitmap(bitmap, {}, { left: '0px', top: '0px', width: width + 'px', height: height + 'px' }) const fontSize = Math.max(Math.floor(width * 0.03), 14) const padding = Math.floor(fontSize * 0.8) const textX = padding const bgHeight = fontSize + padding * 2 canvas.drawRect( { color: 'rgba(0,0,0,0.4)' }, { left: '0px', top: (height - bgHeight) + 'px', width: width + 'px', height: bgHeight + 'px' } ) canvas.drawText(text, { left: textX + 'px', top: (height - bgHeight + padding) + 'px', width: (width - textX * 2) + 'px', height: fontSize + 'px' }, { size: fontSize + 'px', color: '#ffffff' }) const tempPath = `_doc/watermark_${Date.now()}.jpg` canvas.toBitmap(tempPath, {}, () => { bitmap.clear() resolve(tempPath) }, (err) => { bitmap.clear() reject(err) }) }, (err) => reject(err)) }, fail: reject }) // #endif // #ifdef H5 const img = new Image() img.crossOrigin = 'anonymous' img.onload = () => { const width = img.naturalWidth const height = img.naturalHeight const canvas = document.createElement('canvas') canvas.width = width canvas.height = height const ctx = canvas.getContext('2d') ctx.drawImage(img, 0, 0, width, height) const fontSize = Math.max(Math.floor(width * 0.03), 14) const padding = Math.floor(fontSize * 0.8) const bgHeight = fontSize + padding * 2 ctx.fillStyle = 'rgba(0,0,0,0.4)' ctx.fillRect(0, height - bgHeight, width, bgHeight) ctx.fillStyle = '#ffffff' ctx.font = `${fontSize}px sans-serif` ctx.textBaseline = 'middle' ctx.fillText(text, padding, height - bgHeight / 2) resolve(canvas.toDataURL('image/jpeg', 0.9)) } img.onerror = (err) => reject(err || new Error('图片加载失败')) img.src = imagePath // #endif // #ifdef MP-WEIXIN || MP-ALIPAY || MP-BAIDU || MP-TOUTIAO || MP-QQ // 小程序端:跳过水印,直接返回原图 // resolve(imagePath) // #endif }) }