uniapp开发小程序在图片上绘制框并显示在image控件和预览
前言
当我想用一套代码实现全端功能的时候,总会有各种阻力在拉着我,所以我想到了用大刀把它给砍断;
开始表演
h5上绘制图片上绘制一个框并返回base64很简单,如下:
const canvas = document.createElement('canvas');
const image = new Image();
image.crossOrigin = 'anonymous';
image.src = imgSrc;
image.onload = () => {
const canvasWidth = image.width;
const canvasHeight = image.height;
canvas.width = canvasWidth;
canvas.height = canvasHeight;
const ctx = canvas.getContext('2d');
if (!ctx) {
reject('Failed to get canvas context');
return;
}
ctx.drawImage(image, 0, 0, canvasWidth, canvasHeight);
ctx.strokeStyle = strokeStyle;
ctx.lineWidth = lineWidth;
bbox.forEach((bboxItem) => {
const [x1, y1, x2, y2] = bboxItem.map(Number);
ctx.strokeRect(
x1,
y1,
Math.min(x2, canvasWidth) - x1,
Math.min(y2, canvasHeight) - y1
);
});
const base64 = canvas.toDataURL('image/jpeg');
但是在小程序上就会出现 document not found;小程序上不支持这样的写法,而且最后的canvas.toDataURL(‘image/jpeg’);方法也找不到!
主角小程序上演
现在开始用uniapp强大的API接口了,首先小程序上页面必须有canvas控件
<!-- #ifdef MP-WEIXIN -->
<canvas v-if="true" canvas-id="canvas" id="canvas" class="canvas"
:style="{width:canvasWidth+'px',height:canvasHeight+'px'}"></canvas>
<!-- #endif -->
创建canvas对象
const canvas = uni.createCanvasContext('canvas');
根据图片地址先把图片下载下来使用接口:uni.downloadFile获取到临时文件地址,再根据接口uni.getImageInfo获取图片的信息;
canvas.drawImage(res.tempFilePath, 0, 0, canvasWidth,
canvasHeight);
const [x1, y1, x2, y2] = [100,100,200,200];
canvas.strokeRect(x1,y1,Math.min(x2, canvasWidth) - x1,Math.min(y2, canvasHeight) - y1);
canvas.draw(false.setTimeout(()=>{
uni.canvasToTempFilePath({
canvasId: 'canvas',
success: (res) => {
uni.getFileSystemManager().readFile({
filePath: res.tempFilePath,
encoding: 'base64',
success: (fileRes) => {
base64Data ='data:image/png;base64,' +fileRes.data;//转换成的base64文件
}})
fail: (err) => {
console.error('读取文件失败',err);
}
}})
最后获取到的base64直接可以显示在image标签上,也可以预览,别的按照你们自己的业务实现!
总结
h5和小程序的有些实现方法不一样,其实有些是通的;看看小程序的API接口,实现也就不难了。小程序就多了一个下载到本地,本地生成一个临时文件,根据canvas来操作这个临时文件,前提是必须有一个canvas控件,具体动手试一下!