近日,在写公司项目的时候接到一个需求:对已加载的大图中可截取部分图片用来入库或者布控,说白了就是截图嘛,于是我使用了vue-cropper来完成。完成后因为前边也没自己实现过,所以就想看看是如何实现的。因此本文写的是最简易基础的实现方法用作学习,肯定有考虑不周的地方,还请大家谅解。工作中还是使用成熟的轮子为好。

一、准备工作

本文中我所使用的环境为vue2 。现在可以在随便一个vue项目中新建一个vue文件开始了。

二、基本结构

在本文中会使用到两个canvas,一个用来绘制我们要加载的图片,一个用来绘制矩形框选区域,就像下面这样,并且在两个canvas身上分别加上ref属性。

html

<template><div><div class="wrap"><canvas id="canvas" ref="imgCanvas"></canvas><canvasid="drawCanvas"ref="drawCanvas"></canvas></div></div>
</template>

下方样式设置两个canvas重叠

<style>
#drawCanvas {position: absolute;top: 0;left: 0;
}
.wrap {position: relative;
}
</style>

三、添加功能

首先我们需要将两个canvas的宽高都设置为相同的,由于上面没有设置canvas的宽高,因此我们在data选项中添加好需要的宽高数据 width: 500,height: 300,稍后将它设置为canvas的大小,请记住,不要用css设置canvas的大小,这其实是将canvas拉伸了。然后在data中添加 ctx 和 imgCtx两个属性用于保存上下文。 接着在mounted生命周期中对canvas进行操作,并且获取到要加载的图片

 let imgCanvas = this.$refs.imgCanvas;//绘制图片的canvaslet drawCanvas = this.$refs.drawCanvas;//绘制框选款的canvas//设置两个canvas的宽高imgCanvas.width = this.width;imgCanvas.height = this.height;drawCanvas.width = this.width;drawCanvas.height = this.height;//获取两个canvas的上下文并且保存在data中this.ctx = drawCanvas.getContext("2d");this.imgCtx = imgCanvas.getContext("2d");//加载图片let img = new Image();img.src = "https://www.auok.ltd/background.jpg";img.crossOrigin = "anonymous";img.onload = () => {console.log("加载完成", img);//图片加载完成后开始绘制图片this.imgCtx.drawImage(img, 0, 0, this.width, this.height);};

以上步骤搞定后现在的页面中应该如下面一样了

1.鼠标按下
2.鼠标抬起
3.鼠标移动
4.鼠标移出

我们来改写一下模板结构,像下面这样

<template><div><div class="wrap"><canvas id="canvas" ref="imgCanvas"></canvas><canvasid="drawCanvas"ref="drawCanvas"@mousedown="onMouseDown"@mousemove="onMouseMove"@mouseup="onMouseUp"@mouseleave="onMouseLeave"></canvas></div><img :src="curSrc" alt="" style="margin: 10px 10px 0 0" /><canvas id="outCanvas"></canvas></div>
</template>

然后在methods中添加对应的onMouseDown、onMouseUp、onMouseMove、onMouseLeave四个方法。然后我们来编写这四个方法就好

onMouseDown

这个方法是鼠标按下事件的监听处理函数。主要负责以下几点

1.清除drawCanvas
2.获取鼠标按下时的位置
3.设置一下绘制线条的样式

代码如下: 编写这个方法前我们要现在data中增加ddownPoint和down两个属性用来存储点的位置标识鼠标是否按下

 onMouseDown(e) {console.log("鼠标按下", e.offsetX, e.offsetY);this.downPoint = [e.offsetX, e.offsetY];this.down = true;this.ctx.strokeStyle = "#fff";this.ctx.lineWidth = 2;}

onMouseMove

鼠标按下了,下面就要移动了。此方法是鼠标移动的监听处理函数。负责以下几点

1.获取鼠标移动的位置
2.绘制矩形选框
3.绘制遮罩层

 onMouseMove(e) { //鼠标未按下不执行操作if (!this.down) {return;}console.log("鼠标移动", e.offsetX, e.offsetY);//当前鼠标移动的位置let movePoint = [e.offsetX, e.offsetY];this.ctx.fillStyle = "rgba(0,0,0,.5)";//设置遮罩层填充颜色//清空drawCanvasthis.ctx.clearRect(0, 0, this.width, this.height);//使用设置的填充颜色来设置drawCanvas的颜色this.ctx.fillRect(0, 0, this.width, this.height);//清除指定区域的颜色,因为需要绘制的选框中间是没有颜色的,不然的话选框区域都是遮罩层的颜色。如下图this.ctx.clearRect(downPoint[0],downPoint[1],movePoint[0] - this.downPoint[0],movePoint[1] - this.downPoint[1]);//绘制描边矩形 四个参数是x坐标 , y坐标 , 矩形的长,矩形的宽this.ctx.strokeRect(downPoint[0],downPoint[1],movePoint[0] - this.downPoint[0],movePoint[1] - this.downPoint[1]);},

onMouseUp

这个方法是鼠标松开按键的事件处理函数,主要负责

1.获取鼠标松开的坐标
2.获取框选部分的图片 上面的步骤中截图区域已经选择完成。接下来就是要获取截图部分的图片了。

代码如下

 onMouseUp(e) {console.log("鼠标抬起", e.offsetX, e.offsetY);//获取坐标let upPoint = [e.offsetX, e.offsetY];//重置鼠标按下状态this.down = false;//获取指定区域的图片数据let cutImgData = this.imgCtx.getImageData(this.downPoint[0],this.downPoint[1],upPoint[0] - this.downPoint[0],upPoint[1] - this.downPoint[1]);//获取返回的图片数据中的宽高let { width, height } = cutImgData;console.log(cutImgData);//创建一个用于放置图片的canvas用来输出图片let outCanvas = document.createElement("canvas");let outCtx = outCanvas.getContext("2d");outCanvas.height = height;outCanvas.width = width;//将图片放置到canvas上outCtx.putImageData(cutImgData, 0, 0);//以blob的形式输出图片outCanvas.toBlob((blob) => {this.curSrc = URL.createObjectURL(blob);}

通过调用getImageData获取了图片指定区域的数据,然后将获取到的图片数据使用putImageData放到创建好的canvas中,再通过canvas的toBlob或者toDataURL方法就可以输入图片的二进制数据或者base64字符串了,这里我用的是blob,再通过URL.createObjectURL获取到图片的本地地址,这种形式:blob:http://localhost:8080/e835d581-cdfe-48ff-b562-743bfcd4970d,可以用来显示或者上传。 在模板中添加一个img标签,并且在data中添加cruSrc属性,最后就如下图

 <img :src="curSrc" alt="" style="margin: 10px 10px 0 0" />

onMouseLeave

这个方法是在鼠标移出canvas区域后重置canvas的状态的。将鼠标状态down重置为false,然后再清除canvas。

四、总结

如果要实际的实现一个和vue-cropper功能差不多的是比较复杂,要考虑很多东西,比如图像的缩放比例、选框的移动及大小调整之类的。这些部分还没有写。

以上就是本文的全部内容了,如有错误欢迎指正!

最后

整理了75个JS高频面试题,并给出了答案和解析,基本上可以保证你能应付面试官关于JS的提问。



有需要的小伙伴,可以点击下方卡片领取,无偿分享

这应该是最简单基础的图片裁剪方法了吧相关推荐

  1. Cropper – 简单的 jQuery 图片裁剪插件

    Cropper 是一个简单的 jQuery 图像裁剪插件.它支持选项,方法,事件,触摸(移动),缩放,旋转.输出的裁剪数据基于原始图像大小,这样你就可以用它们来直接裁剪图像. 如果你尝试裁剪跨域图像, ...

  2. 一个简单的 jQuery 图片裁剪插件----cropper

    浏览器支持 Chrome (latest 2) Firefox (latest 2) Internet Explorer 8+ Opera (latest 2) Safari (latest 2) C ...

  3. python动态旋转图片_python简单实现旋转图片的方法

    本文实例讲述了python简单实现旋转图片的方法.分享给大家供大家参考.具体实现方法如下: # rotate an image counter-clockwise using the PIL imag ...

  4. 简单的压缩图片的方法,压缩图片大小的步骤

    我们在日常生活中也会遇到比较大的图片,比较大的图片文件比较麻烦,上传到网站论坛做头像都传不上去,大家可以将图片文件进行简单的压缩,然后进行上传,教给大家一种简单的压缩图片的方法. 1:先要将自己的图片 ...

  5. 图片裁剪软件有哪些?这几种图片裁剪方法很有用

    裁剪图片是一项非常有用的技能,不仅可以提高设计和制作效率,还能让图片更加符合我们的需求,使其更加美观实用.当我们需要使用图片时,裁剪图片可以让我们更好地掌控图片的外观和内容,把不符合尺寸或者是不相关的 ...

  6. 两种简单的网页图片替换方法

    网站具体是由图片.文字.视频组成的,现在搭建网站,一般都是利用模板建站的方式去做,那么我们拿到模板以后,想要去对这个模板一些图片位置进行修改,应该怎么去做呢?那么基于wordpress的模板建站方式, ...

  7. 【jQuery插件分享】Cropper——一个简单方便的图片裁剪插件

    插件介绍 这是一个我在写以前的项目的途中发现的一个国人写的jQuery图像裁剪插件,当时想实现用户资料的头像上传功能,并且能够预览图片,和对图片进行简单的裁剪.旋转,花了不少时间才看到了这个插件,感觉 ...

  8. 简单高效的图片降噪方法

    图片降噪在很多场合下都要使用到,譬如我遇到的医疗产品. 计算机通过USB口从医疗产品中获取图像,但由于硬件的原因,清晰度一直不够,有很多噪点. 降噪不可避免.降噪算法就是主要问题了. 下面介绍一种简单 ...

  9. 编辑图片,简单的去除图片水印方法

    喜欢追剧的人,很多都会喜欢在网上找一些剧照,剧照经过处理后都会很高清.所以,上传的人一般都会添加上水印,可是图片一旦有了水印,就会让人没有了要保存的想法了. 图片水印的去除,在网上找的图片总是会有水印 ...

最新文章

  1. 汇编程序设计与计算机体系结构软件工程师教程笔记:处理器、寄存器简介
  2. 大话WiFi省电模式
  3. Java Review - 并发编程_独占锁ReentrantLock原理源码剖析
  4. iPhone屏幕做一个最上层全屏幕的layer
  5. SAP plant and location
  6. Open vSwitch(OVS)文档
  7. stm32编码器正反转计数程序_如何高效的扩展定时/计数器?
  8. POJ--1300--Door Man【推断无向图欧拉通路】
  9. php俄语包,俄语资源汇总 - 俄语 | Russian | Pусский - 声同小语种论坛 - Powered by phpwind...
  10. HTML5 Audio时代的MIDI音乐文件播放 .
  11. ffmpeg java_Java 调用 FFMPEG 的坑人之处
  12. Android接入google地图
  13. 复现Reasoning with Heterogeneous Graph Alignment for Video Question Answering
  14. 0712-插曲-对拍
  15. 百度Clouda的初步探索
  16. 图像处理:基于cv2.inpaint()图像修补
  17. 学生评教系统--教师评教
  18. python简易爬虫获取A股上证所有股票历史数据
  19. Photoshop调出清晰的阴雨天气山水风景照
  20. 人力资源战略规划新思考

热门文章

  1. 802.11n能够提供600M最大速率的计算方法
  2. PostgreSQL文本搜索(六)——词典
  3. word的图形尺寸快速调整方法
  4. python3 scrapy实战:爬取猎聘网招聘数据至数据库(反爬虫)
  5. 《谋圣鬼谷子》曝概念海报
  6. STM32单片机使用SEGGER J-Flash 烧录的方法
  7. UEX 3.3.0.4 For Ubuntu 试用期30天到期的解决办法
  8. 2020年中国锦纶行业现状与竞争格局分析,可再生锦纶市场未来可期「图」
  9. 加密艺术市场与艺术家 | 区块链x艺术交叉学科
  10. CString、TCHAR*、char*转换