小程序上传+相机水印功能_vue3

小程序上传+相机水印功能_vue3

组件构成:wxImgUpload_v3 + pictureMark_v3
wxImgUpload_v3pictureMark_v3
图片上传组件图片水印组件
直接引用内置于wxImgUpload_v3
参数说明
1.wxImgUpload_v3
参数说明类型默认/可选值
count最多限制上传数量Number9
mediaType文件类型String[‘image’, ‘video’]
sourceTypealbum 从相册选视频,camera 使用相机拍摄String[‘album’, ‘camera’]
camera相机前后置摄像头String‘front’、‘back’,默认’back’
isMark是否开启水印(用于调用pictureMark_v3关键参数)Booleantrue
markParams水印参数Object[a,b,c,d]
水印数据格式案例:
 let params = [
            '时间:' + prop.markParams.selectDate,
            '地点:' + prop.markParams.address + prop.markParams.address + prop.markParams.address + '123',
            '距离:' + prop.markParams.distance + '  km ',
            prop.markParams.manageStatus === 'WX' ? '管护状态:维修' : prop.markParams.manageStatus === 'ZC' ? '管护状态:正常' : '管护状态:停用',
            '设施情况描述:' + prop.markParams.questionDesc
        ];
2.pictureMark_v3
/* 获取图片信息  */
const loadImage = (params, imgFiles, ctx, currentRefs, callback) => {
    state.currentRefs = currentRefs;
    uni.showLoading({
        title: '图片加载中...'
    });
    imgFiles.forEach(item => {
        uni.getImageInfo({
            src: item.tempFilePath,
            success: (res) => {
                state.dynamicsHeight = res.height;
                state.dynamicsWidth = res.width;

                /* 图片的宽高比  */
                createCanvas(params, res.path, ctx, currentRefs, callback);
            },
            complete() {
                uni.hideLoading();
            }
        });

    });

};
参数说明补充备注
params水印文字信息需要打印的水印数据
params照片信息由uni.chooseMedia获取的用户拍摄或者选择的图片
ctxcreateCanvasContext创建的canvas实例一个canvas组件的实例对象
currentRefscurrentRefs 当前组件的实例通过vue的refs获取到的pictureMark_v3组件实例本身
callback回调函数通过回调函数生成带水印的临时图片地址
const createCanvas = (params, tempFilePath, context, currentRefs, callback) => {
    context.draw();
    uni.showLoading({
        title: '生成水印中...'
    });
    let boxWidth = 710; //背景框宽度
    let TitHeigth = 100; // 头部框高度
    let BodyHeigth = 410; // 内容框高度
    let startX = 10; //x起始位置
    let startY = 480; //y高度起始位置(图片高度-该值得到canvas的y轴坐标)
    let radius = 10; //圆角半径弧度
    let textOffsetY = 40;
    let textOffsetX = 0;

    let x = startX, //x起始位置
        y = state.dynamicsHeight - startY - TitHeigth, //y起始位置
        r = radius; //圆角
        // 绘制照片
    context.drawImage(tempFilePath, 0, 0, state.dynamicsWidth, state.dynamicsHeight);
    //  绘制title圆角边框
    context.beginPath();
    context.moveTo(x + r, y);
    context.fillStyle = 'rgba(56, 175, 50, 0.6)'; //矩形填充颜色
    context.lineTo(x + boxWidth - r, y);
    context.arc(x + boxWidth - r, y + r, r, Math.PI * 1.5, Math.PI * 2);
    context.lineTo(x + boxWidth, y + TitHeigth);
    context.lineTo(x, y + TitHeigth);
    context.lineTo(x, y + r);
    context.arc(x + r, y + r, r, Math.PI, Math.PI * 1.5);
    context.fill();

    //  绘制title
    context.fillStyle = '#F8F8FF';
    context.setFontSize(44);
    context.fillText('上报信息', x + (boxWidth / 2) - 90, y + 70);

    //  绘制context圆角边框
    let x1 = startX, //x起始位置
        y1 = state.dynamicsHeight - startY, //y起始位置
        r1 = radius; //圆角
    context.beginPath();
    context.moveTo(x1 + r1, y1);
    context.fillStyle = 'rgba(0, 0, 0, 0.2)'; //矩形填充颜色
    context.lineTo(x1 + boxWidth, y1);
    context.lineTo(x1 + boxWidth, y1 + BodyHeigth + r1);
    context.arc(x1 + boxWidth - r1, y1 + BodyHeigth - r1, r1, 0, Math.PI * 0.5);
    context.lineTo(x1 + r1, y1 + BodyHeigth);
    context.arc(x1 + r1, y1 + BodyHeigth - r1, r1, Math.PI * 0.5, Math.PI);
    context.lineTo(x1, y1);
    context.fill();

    // 绘制context
    let yAxis = state.dynamicsHeight - startY,
        xAxis = 20; // context Y轴0偏移
    context.fillStyle = '#F8F8FF';
    context.font = 'normal blod 38px Arial, sans-serif';
    console.log('state.dynamicsWidth', state.dynamicsWidth);
    let lineidx = 1; //行数
    let lineMaxWidth = boxWidth - 30; // 文字最大宽度
    let drawIndex = 0; // 当前绘制内容的索引
    let drawTxt = ''; // 当前绘制内容的索引
    params.forEach((item, index) => {
        drawIndex = 0;
        if (context.measureText(item).width <= lineMaxWidth) {
            context.fillText(item, xAxis, yAxis + (textOffsetY * lineidx));
            lineidx = lineidx + 1;
        } else {
            for (var i = 0; i < item.length; i++) {
                drawTxt += item[i]; //给行内压入文字
                if (context.measureText(drawTxt).width >= lineMaxWidth) {
                    context.fillText(item.substring(drawIndex, i + 1), xAxis, yAxis + (textOffsetY * lineidx));
                    drawIndex = i + 1; // 记录当前行最后一个字符串的下一个idnex,用于绘制下行第一个字
                    lineidx = lineidx + 1; // 行数+1
                    drawTxt = ''; // 重置绘制的内容
                } else {
                    // 最后不满一行绘制
                    if (i + 1 === item.length) {
                        context.fillText(item.substring(drawIndex, item.length), xAxis, yAxis + (textOffsetY * lineidx));
                        drawIndex = i + 1; // 记录当前行最后一个字符串的下一个idnex,用于绘制下行第一个字
                        lineidx = lineidx + 1; // 行数+1
                        drawTxt = ''; // 重置绘制的内容
                    }
                }
            }
        }

    });

    context.draw(false, () => {
        uni.canvasToTempFilePath({
            canvasId: 'firstCanvas',
            success: res => {
                // 成功回调
                callback(res.tempFilePath);
            },
            fail: err => {
                console.log(err);
            },
            complete: () => {
                uni.hideLoading();
            }
        }, currentRefs);
    });

};
  • 9
    点赞
  • 6
    收藏
    觉得还不错? 一键收藏
  • 1
    评论
您可以使用`Vue.js`和`HTML5`的`MediaDevices.getUserMedia()`方法来实现打开带水印相机应用程序。以下是实现此目标的步骤: 1. 建立Vue.js应用程序并导入所需的库。 ```javascript import Vue from 'vue' import watermark from 'watermarkjs' ``` 2. 在Vue.js模板中呈现带有水印的视频元素和拍照按钮。 ```html <template> <div> <video ref="video" autoplay></video> <button @click="takePicture">Take Picture</button> </div> </template> ``` 3. 在Vue.js组件中初始化视频元素和水印。 ```javascript export default { mounted() { this.initCamera() this.initWatermark() }, methods: { initCamera() { navigator.mediaDevices.getUserMedia({ video: true }) .then(stream => { const video = this.$refs.video video.srcObject = stream video.onloadedmetadata = () => { video.play() } }) }, initWatermark() { const video = this.$refs.video const canvas = document.createElement('canvas') const ctx = canvas.getContext('2d') const wm = watermark([video, 'watermark text'], { init(img) { canvas.width = img.naturalWidth canvas.height = img.naturalHeight }, render(img, data) { ctx.drawImage(img, 0, 0) ctx.font = 'bold 32px Arial' ctx.fillStyle = 'white' ctx.fillText(data[1], 10, canvas.height - 10) } }) setInterval(() => { wm.render() video.srcObject = canvas.captureStream() }, 1000) }, takePicture() { const video = this.$refs.video const canvas = document.createElement('canvas') canvas.width = video.videoWidth canvas.height = video.videoHeight const ctx = canvas.getContext('2d') ctx.drawImage(video, 0, 0, canvas.width, canvas.height) const image = canvas.toDataURL() console.log(image) } } } ``` 4. 运行应用程序并单击“Take Picture”按钮以拍摄照片。 这样,您就可以在Vue.js应用程序中创建带有水印相机应用程序。请注意,此示例仅适用于最新版本的Chrome和Firefox浏览器。
评论 1
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值