cangqinglang

零、 介绍

本篇文章主要介绍如何从零开始做一个完整的图片裁剪组件

背景

一个图片裁剪组件的应用场景其实比较多,相应的第三方插件也不少,但有时候会需要一些特定的功能,比如想有个特定样式的裁剪框,想批量裁剪,甚至想直接裁出定制化的尺寸等等,这时就只能手写一个裁剪组件了。

大致流程

300

一、上传读取图片

上传图片时,用onChange事件来获取该file对象,里面会包含文件的name,size,type,和修改时间等信息(只读),预览图片之前可以通过这些信息来限制上传图片的格式、类型等等。

handleChange = (e) => {
        const files = Array.from(e.target.files);
        if (!files.length) {
            // 释放上传系统存储当前值,避免相同文件不触发onchange事件
            this.imageUpload.value = null; 
            return;
        }
        // 上传规则校验(比如图片格式,图片大小限制等等
        ....
}
render() {
  return (
      <div>
          <input
            type="file"
            onChange={this.handleChange} // 监听上传事件
            multiple="true" // 是否批量上传
            accept="image/*" // 控制上传文件的类型,image/*表示接收所有image后缀的文件
            ref={e => {
                this.imageUpload = e;
            }}
        />
    </div>
  )
}
 

⚠️注意点: 使用onChange上传文件时,如果连续两次选择相同的文件,第二次会因为value还是同一个值导致onChange不会触发,所以在第一次上传完之后,需要将input的value置为空

二、Canvas绘制图片

2.1 解析图片信息

利用我们刚刚获取的file文件对象,可以解析出一些图片的关键信息,比如图片的宽、高以及最重要的base64。这里我们主要是通过FileReader.readAsDataURL来实现。

1

触发 FileReader.onload 方法时,会返回一个基于 base64 编码的 data-uri 对象。

// 读取图片原始信息方法
filesInfo = (file) => {
    return new Promise((res, rej) => {
        let reader = new FileReader();
        reader.readAsDataURL(file);
        reader.onload = function(e) {
              // 实例一个Image对象,为了获取宽、高(下文预览图片时需要)
              let image = new Image(); 
            image.onload = function() {
                res({
                    width: image.width, //
                      height: image.height, //
                    // 其他图片信息
                      // ...
                });
            };
            image.src = e.target.result; // base64
              image.crossOrigin = \'Anonymous\'; //解决跨域问题
        };
    });
},
 

其实除了上述还有第二种方式, window.URL.createObjectURL,有兴趣的小伙伴可以自行查阅一下,本文就不再做赘述了。

2.2 预览图片

canvas的宽高分为2种:

  • canvas style样式中的宽高:是整个canvas的宽高,决定了整个canvas context的大小

  • canvas元素属性的宽高:表示canvas的画布大小

因此我们的自适应图片居中策略:

300*300

⚠️关于设备像素比具体可以戳

分类:

技术点:

相关文章:

  • 2021-12-06
  • 2021-08-17
  • 2021-11-05
  • 2022-12-23
猜你喜欢
  • 2022-01-15
  • 2021-12-23
  • 2021-12-19
  • 2022-12-23
  • 2021-11-30
  • 2021-04-30
  • 2021-11-03
相关资源
相似解决方案