vue中实现图片切割并上传

441 阅读2分钟

需求:上传图片时,可以对图片进行切割裁剪,上传切割后的图片

示例:

        切割前:这是一整张图片

1689747982666.jpg

         切割后:得到上下两张图片

1689748189890.jpg

注:题主这里只提供切割图的一种方法思路,具体实现请根据业务场景再做更改

        在看到这个需求后,题主试着在网上找过现成的插件,可惜没找到,但是看到了一个canvas可以实现切图,于是利用canvas实现了此功能。

        废话不多说了,开撕!

        首先,在上传图片时可以拿到file对象,使用file对象转base64去展示图片(这里用这种方法展示图片可以避免一些错误,但不是必须这么做)

getFile(file) {
      const _this = this
      if (window.FileReader) {
        // 创建读取文件的对象
        var fr = new FileReader()
        // 以读取文件字符串的方式读取文件 但是不能直接读取file
        // 该方法结束后图片会以data:URL格式的字符串(base64编码)存储在fr对象的result中
        fr.readAsDataURL(file.raw)
        fr.onloadend = function() {
          _this.$set(_this.form, 'url', fr.result)
          _this.$set(_this.form, 'file', file)
        }
      }
    },

        在展示的图片上移入鼠标展示切割线

1689748093542.jpg

        点击鼠标在图片上增加一条切割线,记录切割线的位置,可以多次添加切割线,这里示例只做切割一次的展示

1689748120343.jpg

        利用canvas.drawImage()实现

    <canvas id="myCan" />

      var canvas = document.getElementById('myCan')
      var ctx = canvas.getContext('2d')
      var img = document.getElementById('img')
      var image = new Image()
      image.src = this.form.url
      const _this = this
image.onload = function() {
    ctx.drawImage(img,sx,sy,swidth,sheight,x,y,width,height);
    const imgBase64 = canvas.toDataURL('image/jpeg', 1.0)
    // imgBase64 得到的就是根据参数切割后的图片base64
}

ctx.drawImage() 参数示例

img规定要使用的图像、画布或视频。
sx可选。开始剪切的 x 坐标位置。
sy可选。开始剪切的 y 坐标位置。
swidth可选。被剪切图像的宽度。
sheight可选。被剪切图像的高度。
x在画布上放置图像的 x 坐标位置。
y在画布上放置图像的 y 坐标位置。
width可选。要使用的图像的宽度(伸展或缩小图像)。
height可选。要使用的图像的高度(伸展或缩小图像)。

如:图片实际为500* 300,在页面展示为50*30,切割线在页面中距图片顶部10px,

则上部分图片base64为:ctx.drawImage(img,0,0,500,100,0,0,500,100);

下部分图片base64为:ctx.drawImage(img,0,100,500,200,0,0,500,200);

注:如果展示的图片有固定的宽高值,传参需要实际的宽高

        拿到切割后的base64,再转为file对象就可以上传了。

        当然,大家有好的方法也可留言讨论,共同进步,(^▽^) ~~~