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

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

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

前言

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

但是需要存下标记图及其标记的具体数据,              。功能其实很简单              ,但刚开始的时候也是费了一些功夫的                    。我将原项目中该功能抽离出来单独写了一个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
python多次赋值(python多值参数是什么)