|
@@ -17,24 +17,19 @@
|
|
|
<!-- 隐藏 canvas -->
|
|
<!-- 隐藏 canvas -->
|
|
|
<canvas
|
|
<canvas
|
|
|
canvas-id="watermarkCanvas"
|
|
canvas-id="watermarkCanvas"
|
|
|
- :style="{
|
|
|
|
|
- width: canvasWidth + 'px',
|
|
|
|
|
- height: canvasHeight + 'px',
|
|
|
|
|
- position: 'fixed',
|
|
|
|
|
- left: '-9999px',
|
|
|
|
|
- }"
|
|
|
|
|
|
|
+ :style="`width: ${canvasWidth}px; height: ${canvasHeight}px; position: fixed; left: -9999px; top: 0`"
|
|
|
/>
|
|
/>
|
|
|
</view>
|
|
</view>
|
|
|
</template>
|
|
</template>
|
|
|
|
|
|
|
|
<script setup lang="ts">
|
|
<script setup lang="ts">
|
|
|
-import { ref, watch } from 'vue'
|
|
|
|
|
|
|
+import { nextTick, ref, watch } from 'vue'
|
|
|
import { getCurrentInstance } from 'vue'
|
|
import { getCurrentInstance } from 'vue'
|
|
|
|
|
|
|
|
-import dayjs from 'dayjs'
|
|
|
|
|
-
|
|
|
|
|
import { useSaveToAlbum } from '@/composables/photo/useSaveToAlbum'
|
|
import { useSaveToAlbum } from '@/composables/photo/useSaveToAlbum'
|
|
|
|
|
|
|
|
|
|
+import { generateWatermark } from '@/utils/generateWatermark'
|
|
|
|
|
+
|
|
|
const visible = defineModel<boolean>('visible', { default: false })
|
|
const visible = defineModel<boolean>('visible', { default: false })
|
|
|
|
|
|
|
|
const props = defineProps<{
|
|
const props = defineProps<{
|
|
@@ -51,8 +46,6 @@ const safeTop = system.safeAreaInsets?.top ?? 0
|
|
|
const safeBottom = system.safeAreaInsets?.bottom ?? 0
|
|
const safeBottom = system.safeAreaInsets?.bottom ?? 0
|
|
|
|
|
|
|
|
const watermarkSrc = ref('')
|
|
const watermarkSrc = ref('')
|
|
|
-const canvasWidth = ref(0)
|
|
|
|
|
-const canvasHeight = ref(0)
|
|
|
|
|
|
|
|
|
|
const close = () => {
|
|
const close = () => {
|
|
|
visible.value = false
|
|
visible.value = false
|
|
@@ -65,85 +58,42 @@ const download = () => {
|
|
|
saveToAlbum(watermarkSrc.value)
|
|
saveToAlbum(watermarkSrc.value)
|
|
|
}
|
|
}
|
|
|
|
|
|
|
|
-/**
|
|
|
|
|
- * 核心:生成水印图
|
|
|
|
|
- */
|
|
|
|
|
-
|
|
|
|
|
const instance = getCurrentInstance()
|
|
const instance = getCurrentInstance()
|
|
|
-const generateWatermark = (fileUrl: string, address: string) => {
|
|
|
|
|
- console.log('fileUrl', fileUrl)
|
|
|
|
|
- console.log('address', address)
|
|
|
|
|
-
|
|
|
|
|
- return new Promise<string>((resolve, reject) => {
|
|
|
|
|
- uni.getImageInfo({
|
|
|
|
|
- src: fileUrl,
|
|
|
|
|
- success(res) {
|
|
|
|
|
- canvasWidth.value = res.width
|
|
|
|
|
- canvasHeight.value = res.height
|
|
|
|
|
-
|
|
|
|
|
- const ctx = uni.createCanvasContext('watermarkCanvas', instance)
|
|
|
|
|
-
|
|
|
|
|
- // 原图
|
|
|
|
|
- ctx.drawImage(fileUrl, 0, 0, res.width, res.height)
|
|
|
|
|
-
|
|
|
|
|
- const scale = res.width / 375
|
|
|
|
|
- const padding = 12 * scale
|
|
|
|
|
- const fontSize = 12 * scale
|
|
|
|
|
- const lineHeight = 18 * scale
|
|
|
|
|
-
|
|
|
|
|
- const textList = [address, dayjs().format('YYYY/MM/DD HH:mm:ss')]
|
|
|
|
|
-
|
|
|
|
|
- ctx.setFontSize(fontSize)
|
|
|
|
|
- const textWidth = Math.max(...textList.map((t) => ctx.measureText(t).width))
|
|
|
|
|
-
|
|
|
|
|
- const boxWidth = textWidth + padding * 2
|
|
|
|
|
- const boxHeight = lineHeight * textList.length + padding
|
|
|
|
|
-
|
|
|
|
|
- const x = padding
|
|
|
|
|
- const y = res.height - boxHeight - padding
|
|
|
|
|
-
|
|
|
|
|
- ctx.setFillStyle('rgba(0,0,0,0.45)')
|
|
|
|
|
- ctx.fillRect(x, y, boxWidth, boxHeight)
|
|
|
|
|
-
|
|
|
|
|
- ctx.setFillStyle('#fff')
|
|
|
|
|
- textList.forEach((text, i) => {
|
|
|
|
|
- ctx.fillText(text, x + padding, y + padding + lineHeight * (i + 1) - 4)
|
|
|
|
|
- })
|
|
|
|
|
-
|
|
|
|
|
- ctx.draw(false, () => {
|
|
|
|
|
- uni.canvasToTempFilePath(
|
|
|
|
|
- {
|
|
|
|
|
- canvasId: 'watermarkCanvas',
|
|
|
|
|
- fileType: 'jpg',
|
|
|
|
|
- success(r) {
|
|
|
|
|
- resolve(r.tempFilePath)
|
|
|
|
|
- },
|
|
|
|
|
- fail: reject,
|
|
|
|
|
- },
|
|
|
|
|
- instance
|
|
|
|
|
- )
|
|
|
|
|
- })
|
|
|
|
|
- },
|
|
|
|
|
- fail: reject,
|
|
|
|
|
- })
|
|
|
|
|
- })
|
|
|
|
|
-}
|
|
|
|
|
|
|
|
|
|
-/**
|
|
|
|
|
- * src 或 address 变化时,重新生成水印
|
|
|
|
|
- */
|
|
|
|
|
|
|
+const canvasWidth = ref(10)
|
|
|
|
|
+const canvasHeight = ref(10)
|
|
|
|
|
+
|
|
|
watch(
|
|
watch(
|
|
|
- () => [props.src, props.address],
|
|
|
|
|
- async ([src, address]) => {
|
|
|
|
|
- if (!src || !address) return
|
|
|
|
|
|
|
+ () => visible.value,
|
|
|
|
|
+ async (val) => {
|
|
|
|
|
+ if (!val) return
|
|
|
|
|
+ if (!props.src || !props.address) return
|
|
|
|
|
+
|
|
|
|
|
+ await new Promise<void>((resolve, reject) => {
|
|
|
|
|
+ uni.getImageInfo({
|
|
|
|
|
+ src: props.src,
|
|
|
|
|
+ success(res) {
|
|
|
|
|
+ canvasWidth.value = res.width
|
|
|
|
|
+ canvasHeight.value = res.height
|
|
|
|
|
+ resolve()
|
|
|
|
|
+ },
|
|
|
|
|
+ fail: reject,
|
|
|
|
|
+ })
|
|
|
|
|
+ })
|
|
|
|
|
+
|
|
|
|
|
+ // 等 canvas 真正挂载完成
|
|
|
|
|
+ await nextTick()
|
|
|
try {
|
|
try {
|
|
|
- watermarkSrc.value = await generateWatermark(src, address)
|
|
|
|
|
- console.log('watermarkSrc.value', watermarkSrc.value)
|
|
|
|
|
- } catch (error) {
|
|
|
|
|
- console.log('err', error)
|
|
|
|
|
|
|
+ watermarkSrc.value = await generateWatermark({
|
|
|
|
|
+ imageUrl: props.src,
|
|
|
|
|
+ address: props.address,
|
|
|
|
|
+ canvasId: 'watermarkCanvas',
|
|
|
|
|
+ instance,
|
|
|
|
|
+ })
|
|
|
|
|
+ } catch (err) {
|
|
|
|
|
+ console.error('generateWatermark error', err)
|
|
|
}
|
|
}
|
|
|
- },
|
|
|
|
|
- { immediate: true }
|
|
|
|
|
|
|
+ }
|
|
|
)
|
|
)
|
|
|
watch(visible, (val) => {
|
|
watch(visible, (val) => {
|
|
|
if (val) {
|
|
if (val) {
|