首页IT科技canvas实现图片编辑(canvas实现图片标记)

canvas实现图片编辑(canvas实现图片标记)

时间2025-06-20 20:09:24分类IT科技浏览4742
导读:前言 由于业务需求,需要有一个图片标记功能,其实就是对图片画框画线做标记,类似微信的图片编辑...

前言

由于业务需求            ,需要有一个图片标记功能                  ,其实就是对图片画框画线做标记      ,类似微信的图片编辑

但是需要存下标记图及其标记的具体数据,            。功能其实很简单            ,但刚开始的时候也是费了一些功夫的                  。我将原项目中该功能抽离出来单独写了一个demo                  ,作为记录      ,同时你们在开发过程中有类似需求的话也可以参考一下该思路      ,其中有不足之处还请指出来      。

实现目标

1            、定点缩放            。

2                  、图片拖拽                  。

3      、图片中绘制点            、直线                  、矩形      、圆形      、多边形      。

4                  、上传原图      。

5            、下载标注图                  。

6      、记录标记数据            。

具体效果

这是在线浏览地址      。

这是源码地址                  。

实现思路

项目是纯原生canvas实现的                  ,没使用任何其他插件            。由于canvas没有图层的概念            ,实现切换不同的绘制模式时有一点麻烦。具体方案是:分别单独存下每次绘制的数据      ,再将该数据添加到一个大列表中(如下图中的canvasData)                  ,每次绘制图形时都需要重绘该大列表            ,若需要操作绘制的图形,则变动大列表中对应的数据后重绘即可                  。

具体逻辑

1                  、绑定事件                  。先添加画布canvas                  ,并指定画布尺寸与绑定各种事件:滚轮事件(mousewheel)            、右键事件(contextmenu)、鼠标按下事件(mousedown)                  、鼠标松开事件(mouseup)                  、鼠标移动事件(mousemove)、双击事件(dblclick)。

2            、绘制模式            。该功能有五种绘图模式:点模式                  、直线模式      、矩形模式            、多边形模式                  、圆形模式                  。点模式最简单                  ,在鼠标松开事件中绘制点,然后获取到坐标            ,最后将数据添加到大列表中      。

其中canvas绘制点的方法如下                  ,其实就是利用ctx.arc绘制一个实心圆      ,arc四个参数分别为圆心坐标x      、y      、半径                  、起始角度            、终止角度            。

直线模式的绘制是在鼠标移动事件中            ,移动时不停的调用ctx.clearRect清除绘制的图形                  ,然后再不停的绘制大列表的数据      ,鼠标松开后将再将直线绘图数据添加到大列表中      ,从而实现拖拽画线的效果                  。canvas绘制直线的方法如下                  ,其中最主要的便是ctx.lineTo方法      。

矩形模式的绘制与直线绘制一样            ,也是放在鼠标移动事件中的      。拖拽即可绘制出矩形                  。具体canvas绘制矩形的方法如下      ,其中ctx.strokeRect方法四个参数分别为矩形左上角的x      、y坐标                  ,矩形长度                  、矩形宽度            。

多边形绘制模式比较麻烦一点      。我设计的操作模式是            ,右键依次点击多边形的顶点,最后需要闭合时双击左键即可完成绘制                  ,闭合多边形                  ,将多边形数据添加到大列表中                  。这样只需判断每次点击绘制时是否闭合即可,双击事件处理如下            。

圆形模式绘制的绘制与点的绘制类似            ,也是使用ctx.arc。不同的是圆需要计算半径                  ,在鼠标松开的一瞬间记录下坐标      ,使用该坐标平方后再开根即可计算出半径                  。具体绘制方法如下                  。

3            、定点缩放。需要保证鼠标中心位置与图片比例不能改变            ,该功能是绑定鼠标滚动事件的                  ,每次缩放时需要重新计算比例与坐标      ,重绘大列表的数据      ,这是滚动事件的处理                  ,需要注意事件中wheelDelta值的正负            。

这是改变画布的方法            ,画布尺寸是通过缩放倍数与原图尺寸控制的      ,画布位置是通过旧位置加偏移量来控制的                  。需要限制缩放倍数的话控制maxZoom与minZoon即可      。

4、图片拖拽            。该功能的实现则比较简单                  ,点击左键后打开限制拖拽的状态            ,记录拖拽偏移量                  。

鼠标移动时,实时改变画布的top与left即可(这里是通过position: absolute;定位的)      。

5                  、上传原图      。这里的上传并不是上传到服务器中                  ,而是利用input type="file"选取文件到浏览器中处理                  ,需要限制为只选取图片,使用accept="image/jpeg"属性                  。

其中上传的方法如下            ,需要限制文件大小                  ,然后通过createObjectURL获取到url(该url比较特殊      ,只在当前dom页面中有效)            。

最后通过loadBgImg方法返回一个img            ,页面中即可使用该图片                  ,从而实现“上传            ”      。

6                  、下载标注图                  。值得注意的是为防止标记错位      ,需要下载前需要将图片尺寸位置还原      ,然后再获取页面中canvas的DOM                  ,然后通过toDataURL获取到base64            。

将该base64生成转化为Blob            ,然后创建事件      ,使用a标签下载                  ,路径仍然使用createObjectURL获取。

7、记录标记数据                  。记录标记数据的好处是            ,将来若需要单独编辑每个标记,则可以直接改变记录下的数据                  ,然后重绘该数据即可                  。记录数据的逻辑是写在鼠标松开事件中的                  ,每次绘制完标记后都需要将绘图数据push到大列表中。

结语

在开发过程中我还是踩了很多坑的,文章中记录的只是很少的一部分            。还是建议看文章开头的项目源码链接            ,源码中我写了大量详细的注释                  。

创心域SEO版权声明:以上内容作者已申请原创保护,未经允许不得转载,侵权必究!授权事宜、对本内容有异议或投诉,敬请联系网站管理员,我们将尽快回复您,谢谢合作!

展开全文READ MORE
设计模式介绍和单一职责原则的关系(设计模式介绍和单一职责原则)