最好采用等比率缩小全屏显示,先获取屏幕宽度,然后获取图片的真实宽度和高度,最后根据屏幕宽度与图片宽度算出同比率缩小后的屏幕显示的图片高度,然后居中显示,最后导出的时候 destWidth:和 destHeight设置为图片真实的宽高就行了。示例代码如下:
点击查看代码
<template> <view class="image-mask-editor"> <view v-if="!imagePath" class="upload-container"> <button @tap="chooseImage">上传图片</button> </view> <view v-else class="canvas-container" style="position: fixed; top: 0;bottom: 0;left:0;right:0; width: 100%;z-index:3;background-color: black;"> <view style="position: relative;"> <!-- <canvas style="display: none;" canvas-id="myCanvas" :style="canvasStyleexport" ></canvas> --> <image :src="imagePath" mode="widthFix" class="background-image" :style="imgStyle"></image> <canvas canvas-id="maskCanvas" class="maskCanvas" :style="canvasStyle" @touchstart="touchstartmask" @touchmove="touchmovemask" @touchend="touchendmask"></canvas> <view class="controls"> <button @tap="clearMask">清除遮罩</button> <button @tap="getMaskImage">预览遮罩图</button> </view> </view> </view> </view> </template> <script> export default { data() { return { ctx: null, scaleratio: 0, imgrealWidth: 0, imgrealHeight: 0, screenWidth: 0, screenHeight: 0, canvasStyle: '', soureimgPath: "", //原图压缩后与蒙版图尺寸一致 imgStyle: '', imagePath: '', points: [], //路径点集合 isDrawing: false, lastX: 0, lastY: 0, } }, onReady() { // 获取屏幕宽度 uni.getSystemInfo({ success: (res) => { this.screenWidth = res.windowWidth this.screenHeight = res.windowHeight } }) }, methods: { chooseImage() { uni.chooseImage({ count: 1, success: (res) => { this.soureimgPath = res.tempFilePaths[0] this.imagePath = res.tempFilePaths[0] this.$nextTick(() => { this.initCanvas() }) } }) }, initCanvas() { // 获取图片尺寸以设置画布大小 uni.getImageInfo({ src: this.imagePath, success: (imageInfo) => { // 设置 canvas 的实际尺寸为图片尺寸 this.imgrealWidth = imageInfo.width; this.imgrealHeight = imageInfo.height; //this.setCanvasStyle(); // 创建 canvas 上下文 this.ctx = uni.createCanvasContext('maskCanvas', this); const scale = this.screenWidth / this.imgrealWidth; this.scaleratio = scale; // 根据原始宽高比计算正确的高度 const height = this.imgrealHeight * scale; const top = (this.screenHeight / 2) - (height / 2); this.imgStyle = `top:${top}px;`; this.canvasStyle = `width: ${this.screenWidth}px; height: ${height}px;top:${top}px; ` // this.canvasStyleexport = // `width: ${this.imgrealWidth}px; height: ${this.imgrealHeight}px; ` // // 设置 canvas 的绘图尺寸 this.ctx.width = this.screenWidth; this.ctx.height = height; // 将图片绘制到画布上作为尺寸压缩后的原图 // this.ctx.drawImage(this.imagePath, 0, 0, this.screenWidth, height); // this.ctx.draw(); // this.$nextTick(() => { // uni.canvasToTempFilePath({ // canvasId: 'maskCanvas', // success: (res) => { // console.log('原图压缩后图片路径:', res.tempFilePath); // this.soureimgPath = res.tempFilePath; // this.clearMask(); // // uni.previewImage({ // // urls: [res.tempFilePath] // // }) // // uni.saveFile({ // // tempFilePath: res.tempFilePath, // // success: function(res) { // // var savedFilePath = res.savedFilePath; // // } // //}) // // 这里可以进行后续操作,比如上传或显示遮罩图 // }, // fail: (err) => { // console.error('获取遮罩图片失败:', err); // } // }); // }) }, }); }, setCanvasStyle() { // 计算缩放比例 const scale = this.screenWidth / this.imgrealWidth; this.scaleratio = scale; // 根据原始宽高比计算正确的高度 const height = this.canvasHeight * scale; this.canvasStyle = `width: ${this.screenWidth}px; height: ${height}px; transform: scale(1); transform-origin: left top;` }, touchstartmask(e) { this.isDrawing = true; this.lastX = e.changedTouches[0].x; this.lastY = e.changedTouches[0].y; this.drawCircle(this.lastX, this.lastY); }, touchmovemask(e) { if (!this.isDrawing) return; const currentX = e.changedTouches[0].x; const currentY = e.changedTouches[0].y; this.drawCircle(currentX, currentY); this.lastX = currentX; this.lastY = currentY; }, touchendmask() { this.isDrawing = false; }, drawCircle(x, y) { const scaledX = x; const scaledY = y; const radius =30; this.ctx.beginPath(); this.ctx.arc(scaledX, scaledY, radius, 0, Math.PI * 2); this.ctx.fillStyle = 'rgba(255, 255,255, 1)'; this.ctx.fill(); this.ctx.draw(true); }, clearMask() { this.ctx.clearRect(0, 0, this.screenWidth, this.screenWidth * this.scaleratio); this.ctx.draw(); }, getMaskImage() { uni.canvasToTempFilePath({ canvasId: 'maskCanvas', destWidth: this.imgrealWidth, destHeight: this.imgrealHeight, success: (res) => { console.log('遮罩图片路径:', res.tempFilePath); uni.previewImage({ urls: [res.tempFilePath] }) // uni.saveFile({ // tempFilePath: res.tempFilePath, // success: function(res) { // var savedFilePath = res.savedFilePath; // } //}) // 这里可以进行后续操作,比如上传或显示遮罩图 }, fail: (err) => { console.error('获取遮罩图片失败:', err); } }); } } } </script> <style> .maskCanvas { position: absolute; opacity: 0.4; z-index: 2; left: 0; top: 0; } .controls { display: flex; padding-top: 20px; } .background-image { position: absolute; left: 0; z-index: 1; width: 100%; right: 0; } </style>
网友回复