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

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

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

前言

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

但是需要存下标记图及其标记的具体数据,                。功能其实很简单                ,但刚开始的时候也是费了一些功夫的                       。我将原项目中该功能抽离出来单独写了一个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
linux系统文件权限有几种(Linux 基础-文件权限与属性)