适用于拍照或从相册选择图片,每次上传一张,上传多张需要稍作修改
Demo
<template>
<view class="wrap">
<canvas class="canvas" :style="{ width: w + 'px', height: h + 'px' }" canvas-id="firstCanvas"></canvas>
<button class="button" @click="getImg">获取图片</button>
<image mode="aspectFill" :src="src" @click="preview"></image>
</view>
</template>
<script lang="ts" setup>
import { ref, nextTick } from 'vue';
import dayjs from 'dayjs';
/**
* 画布宽度
*/
const w = ref<number>(200);
/**
* 画布高度
*/
const h = ref<number>(200);
/**
* 生成图片的路径
*/
const src = ref<string>('');
/**
* 选择图片
*/
function getImg() {
// 从本地相册选择图片或使用相机拍照
uni.chooseImage({
count: 1,
sizeType: 'compressed',
success: (res: any) => {
setImg(res.tempFilePaths[0]);
},
});
}
/**
* 生成图片
*/
function setImg(url: string) {
// 创建 canvas 绘制上下文,参数(canvas-id, 组件实例)
// vue2 第二个参数即 this
const ctx = uni.createCanvasContext('firstCanvas');
// 获取图片信息
uni.getImageInfo({
src: url,
success: (res) => {
uni.showLoading({
title: '水印添加中...',
mask: true,
});
const currentTime: string = dayjs().format('YYYY-MM-DD HH:mm:ss');
const x: number = res.width / 2 - 270;
const y: number = res.height / 2 - 50;
nextTick(() => {
w.value = res.width / 2;
h.value = res.height / 2;
// 填充一个矩形
ctx.fillRect(0, 0, w.value, h.value);
// 绘制图像到画布,参数(图片资源路径, 图片左上角在目标 canvas 上 x 轴的位置, 图片左上角在目标 canvas 上 y 轴的位置, 绘制图像的宽度, 绘制图像的高度)
ctx.drawImage(res.path, 0, 0, res.width / 2, res.height / 2);
// 设置字体大小
ctx.setFontSize(24);
// 设置填充颜色
ctx.setFillStyle('#ffffff');
// 在画布上绘制被填充的文本,参数(文本, 文本左上角 x 坐标位置, 文本左上角 y 坐标位置)
ctx.fillText(currentTime, x, y);
// 不加异步首次渲染图片有问题
setTimeout(() => {
// 将之前在绘图上下文中的描述(路径、变形、样式)画到 canvas 中,参数(是否接着上一次绘制, 绘制完成后回调)
ctx.draw(false, () => {
// 把当前画布指定区域的内容导出生成指定大小的图片,并返回文件路径
uni.canvasToTempFilePath({
canvasId: 'firstCanvas',
success: (res) => {
src.value = res.tempFilePath;
},
complete: () => {
uni.hideLoading();
},
});
});
}, 500);
});
},
});
}
/**
* 预览图片
*/
function preview() {
uni.previewImage({
urls: [src.value],
current: 0,
});
}
</script>
<style>
.wrap {
display: flex;
flex-direction: column;
align-items: center;
justify-content: center;
position: relative;
}
.canvas {
border: 2rpx solid pink;
background: pink;
width: 100%;
height: 100%;
overflow: auto;
/* 使用定位脱离页面显示区域 */
position: absolute;
top: -1000px;
left: -1000px;
}
.button {
margin: 10px;
}
</style>