裁剪图片原理

FileReader

HTML5定义了FileReader作为文件API的重要成员用于读取文件,根据W3C的定义,FileReader接口提供了读取文件的方法和包含读取结果的事件模型。

创建实例

const reader = new FileReader();

方法

事件

 Blod

Blob是用来支持文件操作的。简单的说:在JS中,有两个构造函数 FileBlob, 而File继承了所有Blob的属性。

所以在我们看来,File对象可以看作一种特殊的Blob对象。

上面说了,File对象是一种特殊的Blob对象,那么它自然就可以直接调用Blob对象的方法。让我们看一看Blob具体有哪些方法,以及能够用它们实现哪些功能:

 Canvas中的ImageData对象

ImageData对象中存储着canvas对象真实的像素数据,它包含以下几个只读属性:

  • width:图片宽度,单位是像素
  • height:图片高度,单位是像素
  • dataUint8ClampedArray类型的一维数组,包含着RGBA格式的整型数据,范围在 0 至 255 之间(包括 255)。

创建一个ImageData对象

使用createImageData() 方法去创建一个新的,空白的ImageData对象。

const myImageData = ctx.createImageData(width, height);

上面代码创建了一个新的具体特定尺寸的ImageData对象。所有像素被预设为透明黑。

得到场景像素数据

为了获得一个包含画布场景像素数据的ImageData对象,可以用getImageData()方法:

const myImageData = ctx.getImageData(left, top, width, height);

在场景中写入像素数据

你可以用putImageData()方法去对场景进行像素数据的写入。

ctx.putImageData(myImageData, dx, dy);

toDataURL 将canvas转为 data URI格式

const canvas = document.getElementById('canvas');
const dataURL = canvas.toDataURL();
console.log(dataURL);

具体实现

第一步:获取文件并读取文件

const handleUpload = (event) => {
  let file = event.target.files[0];
  let fileReader = new FileReader();
  fileReader.onload = (e) => {
    imgUrl.value = e.target.result
    imageRef.value.onload = () => {
      drawImage()
    };
  };
  console.log(file)
  fileReader.readAsDataURL(file);
}

第二步:绘制canvas

const drawImage = () => {
  let image = imageRef.value;
  let canvas = canvasRef.value;
  let ctx = canvas.getContext("2d");
  ctx.clearRect(0, 0, canvas.width, canvas.height);
  let imageWidth = image.width;
  let imageHeight = image.height;
  ctx.drawImage(
    image,
    0,
    0,
    imageWidth,
    imageHeight
  )
}

第三步:裁剪图片

getImageData里的x、y、width、height就是在裁剪图片时选定范围后能获得的值,因为不是裁剪图片的重点,就不展开说了。

const crop = () => {
  let canvas = canvasRef.value;
  let ctx = canvas.getContext('2d');
  const imageData = ctx.getImageData(x, y, width, height);

  let avatarCanvas = document.createElement('canvas');
  avatarCanvas.width = 100;
  avatarCanvas.height = 100;

  let avatarCtx = avatarCanvas.getContext('2d');
  avatarCtx.putImageData(imageData, 0, 0);

  let avatarDataUrl = avatarCanvas.toDataURL();
  clipeUrl.value = avatarDataUrl
}

总结

裁剪图片不难,总结起来就是分为以下两步。

  1. 监听选择文件的onchange事件,选择完图片之后onchange回调里的参数能拿到file对象,然后实例FileReader,FileReader类用于读取文件,包含readAsDataURL方法异步读取文件内容,比如图片base64,onload事件文件读取成功完成时触发,这样就能拿到上传图片的base64,用这个base64去new Image在onload的时候去绘画canvas,用canvas的drawImage把图片画进去,这样完成了第一步。
  2. 在用户选定了裁剪范围裁剪之后,用canvas的getImageData传入x、y、width、height获取画布裁剪范围内的像素数据,再建一个canvas把刚才获取的像素数据putImageData进去,最后toDataURL就能拿到裁剪之后图片的base64了。
  • 0
    点赞
  • 0
    收藏
    觉得还不错? 一键收藏
  • 0
    评论

“相关推荐”对你有帮助么?

  • 非常没帮助
  • 没帮助
  • 一般
  • 有帮助
  • 非常有帮助
提交
评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值