美文网首页
canvas裁剪图片,蒙版选择框

canvas裁剪图片,蒙版选择框

作者: philoZhe | 来源:发表于2018-02-05 19:57 被阅读135次

标签: 前端


[toc]

前言

经常都会遇到一些上传图片前裁剪的需求,这个时候一般都会找到第三方的插件来完成需求。但有时(很不幸)会遇到一些难以处理的情况,例如找不到满足需求的插件或者插件太大而只用到其中一个功能,这种时候就需要自己动手实现一个裁剪工具了。

因此了解一下如何用canvas来实现裁剪功能(其实可以做到更多)是很有必要的,那么现在就开始吧:

原理

分为以下几个步骤

  1. 读取本地图片文件
  2. 图片处理
  3. 输出图片

好像有点太简略。。

简单的例子

下面讲一下自己的例子,功能就是读取图片,左右两个canvas,左边有个半透明蒙版选择裁剪大小,右边输出裁剪后图片。

读取文件

<input type="file">读取本地文件,监听onchange事件,使用Image对象来做个中转方便canvas使用

// 这个img可以供canvas绘图
const img = new Image() 
input.onchange = function(e) {
    const file = e.target.files[0]
    const reader = new FileReader()
    reader.readAsDataURL(file)
    reader.onload = function(e) {
      img.src = e.target.result
    }
}

canvas图片处理

这个例子是鼠标框选截图,因此先加上鼠标事件

let dragging = false
let startX, startY
// 实现拖拽时触发事件
canvas.addEventListener('mousedown', e => {
  dragging = true
  // canvas内部的鼠标位置
  startX = e.offsetX
  startY = e.offsetY
}
canvas.addEventListener('mousemove', e => {
  if (!dragging) return
  // ... 裁剪逻辑
  // ... 立即截图
  // 鼠标移出canvas也要使dragging = false
}
canvas.addEventListener('mouseup', e => {
  dragging = false
})

画个镂空的蒙版表示选择框,这里用到globalCompositeOperation,图片合并效果来实现蒙版,具体见MDN

// 前面已经获取了startX, startY
const ctx = canvas.getContext('2d')
canvas.addEventListener('mousemove', e => {
  if (!dragging) return
  // ... 裁剪逻辑
  
  // 每帧都要清理画布,这里400是canvas的内部像素长宽,不是css的长宽
  ctx.clearRect(0, 0, 400, 400)
  
  // 绘制蒙版
  ctx.save()
  ctx.fillStyle = 'rgba(0,0,0,0.5)'
  ctx.fillRect(0, 0, 400, 400)
  // 开启镂空合并
  ctx.globalCompositeOperation = 'desination-out'
  const currentX = e.offsetX
  const currentY = e.offsetY
  ctx.fillStyle = 'white' // 什么颜色没所谓
  ctx.fillRect(startX, startY, currentX - startX, currentY - startY)
  ctx.restore()
  
  // 绘制底图
  ctx.save()
  // 将图片绘制到蒙版下方
  ctx.globalCompositeOperation = 'destination-over'
  // 参数是:图片;读取图片的起点,长宽;画在canvas上的起点,长宽;
  ctx.drawIamage(img, 0, 0, img.width, img.height, 0, 0, 400, 400)
  ctx.restore()
 
  // ...立即截图
  
  // 鼠标移出canvas也要使dragging = false
}

这样就实现了图片蒙版选择框,下面是截图,很简单

canvas.addEventListener('mousemove', e => {
  if (!dragging) return
  // ... 裁剪逻辑
  
  // 立即截图
  const data = ctx.getImageData(startX, startY, currentX - startX, currentY - startY)
  // 输出在另一个canvas上
  resultCtx.clearRect(0,0,400,400)
  resultCtx.putImage(data, 0, 0)
  
  // 鼠标移出canvas也要使dragging = false
}

输出图片

很简单,用到canvas.toBlob输出二进制数据,然后转File就可以

const mime = 'image/jpeg' // image/png
resultCanvas.toBlob(blob => {
  // 注意是`[blob]`
  const file = new File([blob], '图片.jpg', { type: blob.type })
  // uploadFile(file)
}, mime, 0.9)

一些哲学♂

对实现一个功能感到不知所措的时候,很可能就是对基础的api不熟悉,就像这个例子中,如果不知道canvas有getImageData,putImageData这两个api,那么就不知道如何实现裁剪了,然后就陷入不停找插件的困境。所以,不知道怎么办时别慌,找找js的api。

相关文章

  • canvas裁剪图片,蒙版选择框

    标签: 前端 [toc] 前言 经常都会遇到一些上传图片前裁剪的需求,这个时候一般都会找到第三方的插件来完成需求。...

  • 基于 vue-cropper-elementUI 截图上传插件

    图片裁切 图片裁剪 ...

  • 移动端添加图片裁剪的坑

    本文关键:阻止冒泡、canvas压缩、canvas裁剪、生成黑色图片。 最近项目需要在添加图片时实现裁剪功能,虽然...

  • 蒙版

    如何添加蒙版? ❶ 先【插入图片】并利用裁剪工具按照页面比例裁剪,拉伸成全图型。 ❷ 点击【菜单栏】-【插入】-【...

  • 仿QQ头像裁剪头像效果

    项目中用到头像裁剪需求,于是仿照QQ的效果自己写了一个裁剪图片的控制器,支持设置裁剪区域和蒙版样式,放大和缩小图片...

  • ios-CropImageView-图片和裁剪框都能放大缩小移动

    特点:图片能移动,放大缩小。裁剪框能移动,自由拉伸。移动过程中裁剪框不会超出图片的范围。不在裁剪框里面会有黑色透明...

  • 网址记录

    图片选择器Android的图像裁剪库SmartRefreshLayout刷新加载Android MVP 快速集成框...

  • Angular5中croppie图片裁剪以及 canvas图片压

    关于croppie的图片裁剪工具的使用 裁剪图如下 关于canvas.toDataUrl(type, encode...

  • 作业二+作业三

    作业二:对齐 我把近期的几本书做一个目录 作业三:图片裁剪与蒙版 蒙版做的没有感觉 好突兀

  • 图片剪裁选择框 LCResizableView

    最近遇到裁剪图片的需求,要求选择图片的某一区域进行剪裁,要在图片上呈现选择框来选择区域,这里选择自己开发一款 Sw...

网友评论

      本文标题:canvas裁剪图片,蒙版选择框

      本文链接:https://www.haomeiwen.com/subject/fciizxtx.html