Loading [MathJax]/jax/output/CommonHTML/config.js
前往小程序,Get更优阅读体验!
立即前往
首页
学习
活动
专区
圈层
工具
发布
首页
学习
活动
专区
圈层
工具
MCP广场
社区首页 >专栏 >cropperjs图片裁剪及数据提交文件流互相转换详解

cropperjs图片裁剪及数据提交文件流互相转换详解

作者头像
超级小可爱
发布于 2023-12-21 01:29:11
发布于 2023-12-21 01:29:11
47800
代码可运行
举报
文章被收录于专栏:小孟开发笔记小孟开发笔记
运行总次数:0
代码可运行

cropperjs的主要功能是图片裁剪,是一款前端常用的的图片裁剪工具,可根据相关api配置裁剪出符合自己业务需要的图片,具体使用如下:

  1. npm 引用
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
npm i cropperjs
  • 1
  • 业务中引入
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
import Cropper from 'cropperjs';
  • 1
  • 文件中单独引入方式
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
<link  href="/path/to/cropper.css" rel="stylesheet">
<script src="/path/to/cropper.js"></script>
  • 1
  • 2
  • 初始化图片裁剪
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
new Cropper(element, options)
  • 1

参数:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
element:  需要裁剪的图片元素,一般指本地获取到的img展示标签
options: {
	aspectRatio: 1 / 1, // 裁剪框纵横尺寸比例
	autoCropArea: 1,  // 它应该是一个介于 0 和 1 之间的数字。定义自动裁剪区域大小(百分比), 默认80%
	viewMode: 1,  // 视图模式
	dragMode: "move", // 图片可移动 拖拽模式
	cropBoxMovable:false, //是否可以拖拽裁剪框
	preview:ele,// Dom元素,该元素的预览尺寸样式尽量和aspectRatio尺寸比例保持一致
	responsive: true, // 调整窗口大小时重新渲染裁剪器
	modal:  true,// 在图像上方和裁剪框下方显示黑色模态
	rotatable:  true,// 启用以旋转图像
	scalable: true, // 启用以缩放图像
	zoomable:  true,// 启用以缩放图像
	zoomOnTouch: true,  // 启用通过拖动触摸来缩放图像
	zoomOnWheel: true, //鼠标滚轮缩放
	cropBoxMovable: false, // 裁剪框可移动
	cropBoxResizable: false, // 裁剪框大小可调整
	resizable: false, // 是否允许改变裁剪框大小
	ready: Function,  // 裁剪实例准备完成回调,由于加载图片时有一个异步过程,所以大部分方法都应该在 ready 之后调用
	reset: Function,  // reset() 重置
	clear: Function,  // clear() 清除
	replace(url, hasSameSize): Function,  // url 图片地址, hasSameSize:Boolean,如果新图像与旧图像大小相同,则不会重建裁剪器,只会更新所有相关图像的 URL。这可用于应用过滤器
	...
}

配置项:

viewMode

type:

Number

default:

0

option:

0:无限制 1: 限制裁剪框不超过画布的大小。 2: 限制最小画布大小以适合容器。如果画布和容器的比例不同,最小画布将被其中一个维度中的额外空间包围。 3: 限制最小画布大小以填充容器。如果画布和容器的比例不同,容器将无法在其中一个维度中容纳整个画布。定义裁剪器的视图模式。

如果将viewMode设置为0,裁剪框可以延伸到画布之外,而值为1、2或3将裁剪框限制为画布的大小。viewMode为2或3将额外将画布限制为容器。当画布和容器的比例相同时,2和3之间没有差异。

一. 首先通过input file拿到的本地展示路径有两种:

1.base64格式

2.url格式

base64获取方式: 通过FileReader实例完成后的onload事件获取

url方式:URL.createObjectURL(img) -浏览器可识别的URL图片路径

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
		uploadAwatar (value){ 
          // 图片上传成功后创建 URL
           const fileList = value.target.files; // input file文件
           let img = ele;  // 展示的裁剪图
           if (fileList.length) {
               // url 格式获取可识别的图片路径
               let imgUrl = URL.createObjectURL(fileList[0]);
               img.src = imgUrl;
               img.onload = function(){
                   setCutImg (fileList[0].type); // 裁剪函数
               }
               // 转base64
               / **
                if (typeof FileReader === 'function') { 
	                const reader = new FileReader();
	                reader.readAsDataURL(fileList[0]);
	                reader.onload = (event) => {
	                    var Base64Val = event.target.result;
	                     img.src = Base64Val;
	                    console.log( Base64Val)
	                }
	          } **/
           }
       }	
二. 通过上面有了本地图片展示就满足了图片裁剪的条件,传入dom, 初始化图片裁剪
代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
       /**
       *  @param setCutImg 初始化裁剪函数
       *  @param imgEle 本地获取到的图片展示元素
       */
        setCutImg (type){
            let objOpt = {};
            let winW = cropperPhoto.data.winW - 20;  // 手机端两侧10px间距
            // 正方形头像裁剪,图片竖图,窄图始终以最小的边居中填充裁剪框
            if (imgEle.naturalWidth > imgEle.naturalHeight) {  // 横图
                objOpt = {
                    minCropBoxHeight: winW,
                    minCanvasHeight: winW,
                    minContainerHeight: winW,
                }
            } else { // 竖图
                objOpt = {
                    minCropBoxWidth: winW,
                    minCanvasWidth: winW,
                    minContainerWidth: winW,
                }
            }
            
            cropper = new Cropper(imgEle, {
                ...objOpt,
                aspectRatio: 1 / 1,
                autoCropArea: 1,
                viewMode: 1,
                dragMode: "move", //图片可移动
                cropBoxMovable:false, //是否可以拖拽裁剪框
                zoomOnTouch: true,  
                scalable: true,
                zoomable: true,
                cropBoxMovable: false, // 裁剪框可移动
                cropBoxResizable: false, // 裁剪框大小可调整
                resizable: false, // 是否允许改变裁剪框大小
                ready(){
                    let _this = this;
                        $('.upload-cut').off().on('click', '.cancel', ()=> { // 关闭时处理的逻辑...
                            _this.cropper && _this.cropper.destroy();  // 销毁实例
                        }).on('click', '.sure', async ()=> {  // 确认裁剪的逻辑
                            let cas = _this.cropper.getCroppedCanvas({
                                width: winW,  // 根据需求配置最终裁完的图片宽
                                height: winW,  // 根据需求配置最终裁完的图片高
                                maxWidth: 500,   // 头像所以我这给的最大是500
                                maxHeight: 500, 
                                fillColor: '#fff', // 如果有空白背景色填充
                                imageSmoothingEnabled: false,                            
                            }).toBlob(async(blob) => {
                            	// blob 流提交
                                var formData = new FormData();
                                /* *  
                                // 方法一
                                let arr = new Array(blob);
                                console.log(arr, 'blob');
                                let file = new File(arr, 'file', { type: blob.type,});
                                console.log(file, 'file');
                                formData.append('avatarFile', file); */
                                blob.lastModifiedDate = new Date();
                                blob.name = 'file';
                                blob.filename = 'file';
                                formData.append('avatarFile', blob); // 后端以avatarFile取到blob数据流
                                console.log(formData, 'formData');  // formdata类型数据提交
                                commitData.call(this, formData)   // 数据提交
                            })
                            /**
                            // 方法二
                            // 拿到base64 转成 file流提交
                           	 let base64url = cas.toDataURL(type);
                             let fileData = dataURLtoFile(base64url);
                            console.log(fileData, 'fileData');
                            var formData = new FormData(); // formdata类型数据提交
                            formData.append('avatarFile', fileData);
                           commitData.call(this, formData)  // 数据提交
                           **/

                            /**
                            // 方法三
                            // base64 转blob流转file流提交
                            let base64url = cas.toDataURL(type);
                            // 调用如下
                            let blob = dataURLtoBlob(base64url);
                            let fileData = blobToFile(blob, "fileName");
                            // 上传file就可以了
                            console.log(fileData, 'fileData');
                            var formData = new FormData();  // formdata类型数据提交
                            formData.append('avatarFile', fileData);
                            commitData.call(this, formData) // 数据提交
                            **/
                        })
                }
            });
        }
        function commitData(formData){
        	let _this = this;
			 $.ajax({
                   url: path,
                   	method: "POST",
                   	data: formData,
                   	success: function(res){
                   		....
                   		 _this.cropper && _this.cropper.destroy(); // 裁剪完成释放空间销毁实例
                   	},
                   	error: function(err){
                   		....
                   		 _this.cropper && _this.cropper.destroy(); // 裁剪完成释放空间销毁实例
                   	}
			})
 		}
		
		function dataURLtoFile (dataurl, filename = 'file') {  // base64转file流
            let arr = dataurl.split(',')
            let mime = arr[0].match(/:(.*?);/)[1] // 正则匹配文件类型
            let suffix = mime.split('/')[1]
            let bstr = atob(arr[1])
            let n = bstr.length
            let u8arr = new Uint8Array(n)
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n)
            }
            return new File([u8arr], `${filename}.${suffix}`, {type: mime})
        },
        function dataURLtoBlob(toDataURL) { // base64转blob
            var arr = toDataURL.split(","),
              mime = arr[0].match(/:(.*?);/)[1],
              bstr = atob(arr[1]),
              n = bstr.length,
            u8arr = new Uint8Array(n);
            while (n--) {
                u8arr[n] = bstr.charCodeAt(n);
            }
            return new Blob([u8arr], { type: mime });
        },
        function blobToFile(Blob, fileName) { // blob 模拟file流
            Blob.lastModifiedDate = new Date(); // 或者Date.now(), 文件最近一次的修改时间
            Blob.name = fileName; // 文件名
            return Blob;
        }

new File(data, fileName, options);

第一个参数是个数组,数组项可以是 ArrayBuffer, String 等等,第二个参数fileName指文件名称,第三个options是配置项,支持 type 和 lastModified 属性,type 可以传入 text/plain, text/html 等,lastModified 默认为 Date.now()

实例上的属性

说明

lastModified

返回文件最后的修改时间 ,是个时间戳

lastModifiedDate

返回文件最后的修改时间,一个 Date 对象name文件名称

size

文件大小

webkitRelativePath

文件的本地路径或者

type

文件的MIME 类型

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const file = new File(["foo"], "foo.txt", {
  type: "text/plain",
  lastModified: Date.now()
})
file.name // foo.txt

FileList

FileList 一个 File 的数组,它只有一个方法:

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
files.item(i) //  == files[i]
  • 1

new Blob(data, options);

与File构造函数类似,第一个参数是个数组,数组项可以是 ArrayBuffer, String 等等,第二个是配置项,最常用的就是 type 属性,可以传入 text/plain, text/html 等

属性和方法

说明

sizeBlob

对象中所包含数据的大小(字节)

type

一个字符串,表明该 Blob 对象所包含数据的 MIME 类型

slice(start, end)

返回一个新的 Blob对象,包含了源 Blob 对象中指定范围内的数据。和字符串的 slice 方法类似

stream()

返回一个能读取 blob 内容的 ReadableStream

text()

返回一个 promise 且包含 blob 所有内容的UTF-8格式的字符串

arrayBuffer()

返回一个promise且包含blob所有内容的二进制格式的 ArrayBuffer

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const blob = new Blob(['hello world'], { type: 'text/plain' })
blob.text().then(console.log) // 'hello world'
  • 1
  • 2

FileReader

FileReader 对象允许 Web 应用程序异步读取存储在用户计算机上的文件(或原始数据缓冲区)的内容,可以读取 Blob 和 File 的数据。

一个简单的使用例子,初始化后,监听 load 事件,然后调用读取方法。

代码语言:javascript
代码运行次数:0
运行
AI代码解释
复制
const reader = new FileReader();
reader.onload = function(evt) {
  console.log(evt.target.result);
};
reader.readAsText(file)

事件

说明

onabort

读取操作被中断事件

onerror

读取操作发生错误的事件

onload

读取操作完成的事件

onloadstart

该事件在读取操作开始时触发

onloadend

该事件在读取操作结束时(要么成功,要么失败)触发

onprogress

取 Blob 时触发

方法

说明

abort

中止读取readAsArrayBuffer开始读取数据,读取完后 result 是 ArrayBuffer 对象

readAsBinaryString

开始读取数据,读取完后 result 是二进制数据

readAsData

URL开始读取数据,读取完后 result 是 Base64 字符串

readAsText

开始读取数据,读取完后 result 是字符串

备注:还未亲自测试,但应该可以,值得参考

未经允许不得转载:肥猫博客 » cropperjs图片裁剪及数据提交文件流互相转换详解

本文参与 腾讯云自媒体同步曝光计划,分享自作者个人站点/博客。
如有侵权请联系 cloudcommunity@tencent.com 删除

本文分享自 作者个人站点/博客 前往查看

如有侵权,请联系 cloudcommunity@tencent.com 删除。

本文参与 腾讯云自媒体同步曝光计划  ,欢迎热爱写作的你一起参与!

评论
登录后参与评论
暂无评论
推荐阅读
编辑精选文章
换一批
基于vue的图片裁剪插件vue-cropper ,上传图片到腾讯云存储
网上找了点教程,结合之前框架里就有的修改了一下,没做细节优化处理 demo 16:9的尺寸,自己可以修改 步骤: npm install vue-cropper 组件内使用 import { Vue
〆 千寻、
2020/03/11
4.5K0
图片裁切上传插件cropper的使用
图片上传格式一般是文件格式和base64格式,比较方便的是图片格式,后台可以方便的处理上传的图片。
tianyawhl
2019/11/04
2.1K0
从web图片裁剪出发:了解H5中的Blob
刚开始做前端的时候,有个功能卡住我了,就是裁剪并上传头像。当时两个方案摆在我面前,一个是flash,我不会。另一个是通过iframe上传图片,然后再上传坐标由后端裁剪,而我最终的选择是后者。有人会疑惑,为什么不用H5的Canvas和FormData,第一要考虑ie8的兼容性,第二那时候眼界没到,这种新东西光是听听都怕。   后来随着Mobile项目越做越多,类似的功能开发得也越来越多,Canvas+FormData成为了标配方案。但做的多了却一直没有静下心来研究,浏览器怎么使用H5的方式裁剪并把文件发送出去
李海彬
2018/03/27
2.2K0
从web图片裁剪出发:了解H5中的Blob
从图片裁剪来聊聊前端二进制
首先判断window.navigator.msSaveOrOpenBlob是为了兼容IE(谁要兼容这 xxIE!!)
前端森林
2020/08/21
1.7K0
从图片裁剪来聊聊前端二进制
5分钟搞定图片裁剪,上传
一开始制作这个需求思路有两个,使用canvas原生或者寻找现成的库,对比了一番觉得canvas实现时间耗费较长,且秉承着不重复造轮子的原则(其实是菜),决定使用Cropper.js。官方封装了很多参数、方法、事件,上手容易,文档阅读体验较好、而且便于扩展。
皮小蛋
2020/03/02
5.2K0
vue+vue-cropper实现上传剪裁图片以及上传时压缩图片
代码暂时都是从项目中抽出来的,只适合借鉴参考,等有时间再单独将这些功能单独写项目,欢迎大家提供更好用的方法或指出不足之处,一起进步。
conanma
2021/11/03
3.7K0
Blob、ArrayBuffer、File、FileReader和FormData的区别
Blob、ArrayBuffer、File、FileReader、FormData这些名词总是经常看到,知道一点又好像不知道,像是同一个东西好像又不是,总是模模糊糊,最近终于下决心要弄清楚。
码客说
2019/10/22
5.2K0
在 `el-upload` 上传图片前裁剪:让你的应用更“裁”心,更“剪”美!
大家有没有经历过这样的尴尬时刻?你兴高采烈地上传了一张自拍,结果发现里面有一位不速之客:背景中的路人、凌乱的桌面,或者是某只不安分的宠物。如果你觉得这只是个别现象,那就错了。每一个开发者都知道,用户上传的图片大多不是那么“完美”,裁剪就是你能为用户做的第一件也是最重要的事情。
繁依Fanyi
2024/08/10
3640
玩转前端图片上传
本文讲的图片上传,主要是针对上传头像的。大家都知道,上传头像一般都会分成以下 4 个步骤:
JowayYoung
2020/04/01
3.1K0
玩转前端图片上传
【JS】936- File、Blob、dataURL 和 canvas 的应用与转换
(1) 通常情况下, File 对象是来自用户在一个 input 元素上选择文件后返回的 FileList 对象,也可以是来自由拖放操作生成的 DataTransfer 对象,或者来自 HTMLCanvasElement 上的 mozGetAsFile() API。
pingan8787
2021/04/26
2.5K0
【JS】936- File、Blob、dataURL 和 canvas 的应用与转换
base64与二进制互转,保存内容,文件读写:Blob/FileReader/URL/FormData
html5开发常用的对象有:FileReader  FormData File URL  Blob createObjectURL Uint8Array等,这些在日常开发中,需要做图片转base64,base64转而二进制文件,页面截图让用户下载。
周陆军博客
2023/05/07
3K0
base64图片压缩并转换二进制流
base64 压缩 function dealImage(base64, w, callback) { var newImage = new Image(); var quality = 0.6; newImage.src = base64.url; newImage.setAttribute('crossOrigin', 'Anonymous'); var imgWidth, imgHeight; newImage.onload = function() { imgWid
我乃小神神
2021/12/07
1.9K0
cropper.js 实现HTML5 裁剪图片并上传(裁剪上传头像。)「建议收藏」
github上的官方cropper.js地址是 https://github.com/fengyuanchen/cropperjs
全栈程序员站长
2022/09/01
8K0
图像裁剪库Cropper.js的学习使用
Cropper.js 是一个轻量级的 JavaScript 插件,用于在网页中实现图像裁剪功能。它提供了一个用户友好的界面,允许用户选择和裁剪图像,支持多种配置选项和功能。以下是一些关键特点:
心安事随
2024/08/05
9870
图像裁剪库Cropper.js的学习使用
ajax+php上传图片,等比压缩,canvas压缩减少上传带宽,优化上传速度
至此后端已经压缩完毕,但是如果上传的图片大多是几M的大图,难免浪费上传带宽,而且会导致速度非常慢,影响用户体验,于是可以使用canvas在上传之前压缩一遍,解决速度慢的问题。
躺平程序员老修
2023/09/05
3790
面试官昨天问我对base64的理解,着实被问懵了
我们知道一个字节可表示的范围是 0 ~ 255(十六进制:0x00 ~ 0xFF), 其中 ASCII 值的范围为 0 ~ 127(十六进制:0x00 ~ 0x7F);而超过 ASCII 范围的 128~255(十六进制:0x80 ~ 0xFF)之间的值是不可见字符。
用户3806669
2021/03/25
4.7K0
面试官昨天问我对base64的理解,着实被问懵了
Vue中使用图片裁剪Vue-cropper
(1). 下面代码中的 selectImage 事件是加在所选择的图片上面的,参数为选择图片的地址; (2). 下面代码中的 imgUrl 为最终裁剪的图片提交给服务端保存后的图片链接地址。
越陌度阡
2021/11/11
1.1K0
Vue中使用图片裁剪Vue-cropper
base64转file文件源码记录
我们前后端交互图片的时候,一般我们是用base64进行交互的,但是很多时候我们传递图片的时候很多的后端是需要file文件格式的,而不是base64的,所以这个时候是需要进行一个简单的转变
何处锦绣不灰堆
2020/05/28
1.8K0
基于cropper.js的图片上传和裁剪
项目中要求图片上传并裁剪的功能,之前也有接触过很多图片裁剪插件,效果体验不是很好,今天推荐一款好用的插件-cropper,超级好用,裁剪功能丰富,满足了各种需求。 功能: 1:点击选择图片,弹出文件
王小婷
2018/05/31
6.9K0
图片处理不用愁,给你十个小帮手
本文阿宝哥会为小伙伴们隆重介绍用于图片处理的十个 “小帮手”,他们各个身怀绝技,拥有模糊、压缩、裁剪、旋转、合成、比对等技能。相信认识他们之后,你将能够轻松应对大多数的图片处理场景。
阿宝哥
2020/06/23
5.3K0
推荐阅读
相关推荐
基于vue的图片裁剪插件vue-cropper ,上传图片到腾讯云存储
更多 >
领券
问题归档专栏文章快讯文章归档关键词归档开发者手册归档开发者手册 Section 归档
本文部分代码块支持一键运行,欢迎体验
本文部分代码块支持一键运行,欢迎体验