cropper.js简介
cropper.js是前端将图片裁剪的一个第三方插件,支持图片缩放、移动、旋转,将裁剪后的图片以base64的格式传给后端。
cropper.js的简单使用
依赖插件:
//css
<link rel="stylesheet" href="https://cdn.bootcss.com/cropperjs/2.0.0-alpha.1/cropper.css">
//js
<script src="https://cdn.bootcss.com/cropperjs/2.0.0-alpha.1/cropper.js"></script>
效果图:
其他插件:
//jq是为了书写方便而使用的
<script src="https://cdn.bootcss.com/jquery/3.5.0/jquery.min.js"></script>
代码:
//css
#imgCropper {
width: 500px;
height: 500px;
float: left;
}
#showImg {
margin-left: 20px;
float: left;
}
//html
<div class="">
<input type="file" accept="image/jpg,image/jpeg,image/png" name="file" id="chooseImg" class="hidden"
onchange="selectImg(this)" />
<button class="l-btn cropper-reset-btn">复位</button>
<button class="l-btn cropper-rotate-btn">旋转</button>
<button class="l-btn cropper-scaleX-btn">换向</button>
<button class="l-btn cropper-enlarge-btn">放大</button>
<button class="l-btn cropper-narrow-btn">缩小</button>
<button class="l-btn sureCut" id="sureCut">确定</button>
</div>
<div class="" id="imgCropper">
<img id="tailoringImg">
</div>
//js
var cropper = new Cropper($('#tailoringImg')[0], {
aspectRatio: 1 / 1,// 默认比例
preview: '.previewImg',// 预览视图
guides: false, // 裁剪框的虚线(九宫格)
autoCropArea: 0.5, // 0-1之间的数值,定义自动剪裁区域的大小,默认0.8
movable: false, // 是否允许移动图片
dragCrop: true, // 是否允许移除当前的剪裁框,并通过拖动来新建一个剪裁框区域
movable: true, // 是否允许移动剪裁框
resizable: true, // 是否允许改变裁剪框的大小
scalable: false, //是否可以缩放图片
zoomable: true, // 是否允许缩放图片大小
mouseWheelZoom: false, // 是否允许通过鼠标滚轮来缩放图片
touchDragZoom: false, // 是否允许通过触摸移动来缩放图片
rotatable: true, // 是否允许旋转图片
crop: function (e) {
let cas = cropper.getCroppedCanvas()// 获取被裁剪后的canvas
let base64 = cas.toDataURL('image/jpeg') // 转换为base64
$("#showImg").prop("src", base64)// 显示图片
}
})
// 选择文件触发事件
function selectImg(file) {
//文件为空,返回
if (!file.files || !file.files[0]) {
return
}
var reader = new FileReader()
reader.onload = function (evt) {
var replaceSrc = evt.target.result
// 更换cropper的图片
cropper.replace(replaceSrc, false);// 默认false,适应高度,不失真
}
reader.readAsDataURL(file.files[0])
}
// 旋转
$(".cropper-rotate-btn").on("click", function () {
cropper.rotate(45)
});
// 复位
$(".cropper-reset-btn").on("click", function () {
cropper.reset()
});
// 放大
$('.cropper-enlarge-btn').on('click', function () {
cropper.zoom(2)
})
// 缩小
$('.cropper-narrow-btn').on('click', function () {
cropper.zoom(-2)
})
// 换向
var flagX = true
$(".cropper-scaleX-btn").on("click", function () {
if (flagX) {
cropper.scaleX(-1);
flagX = false;
} else {
cropper.scaleX(1);
flagX = true;
}
flagX != flagX;
})
///后端是通过图片流的模式去判断前端上传的是否是图片,所以我们需要base64编码转换为blob文件对象
//方法一:
function convertBase64UrlToBlob(urlData) {
//去掉url的头,并转换为byte
var bytes = window.atob(urlData.split(',')[1])
//处理异常,将ascii码小于0的转换为大于0
var ab = new ArrayBuffer(bytes.length)
var ia = new Uint8Array(ab)
for (var i = 0; i < bytes.length; i++) {
ia[i] = bytes.charCodeAt(i)
}
return new Blob([ab], { type: 'image/png' })
}
//方法二:
function dataURLtoBlob(dataurl) {
var arr = dataurl.split(','),
mime = arr[0].match(/:(.*?);/)[1],
bstr = atob(arr[1]),
n = bstr.length,
u8arr = new Uint8Array(n);
while (n--) {
u8arr[n] = bstr.charCodeAt(n);
}
//[u8arr] [] 不能省略
return new Blob([u8arr], { type: mime });
}
//确定按钮
$('#sureCut').on('click',function(){
let fromdata = new FormData()
let cas = cropper.getCroppedCanvas()// 获取被裁剪后的canvas
let base64 = cas.toDataURL('image/jpeg') // 转换为base64
/* 这里需要传第三个值,因为我们是通过blob生成的文件,后端可能会通过两种判断方式来判断前端上传的是否是图片
一种是图片流,一种是判断文件后缀,,我们上传的是图片,但是可能因为我们的文件后缀名而导致上传不上去(实际上是上传上去了, 但是因为不满足后端的条件而没存到数据库里)
*/
fromdata.append('file', convertBase64UrlToBlob(base64), '测试.png')
//调接口发送数据
})
node端处理
如果我们是通过node包装接口上传给后端,包装的接口可以看我的博客多文件上传node包装接口分享
如果是存到本地的话,只需把base64编码给上传就行了即把上边的
fromdata.append('file', convertBase64UrlToBlob(base64), '测试.png')
//修改为
fromdata.append('file', base64)
node端
router.post('/upload',(req,res)=>{
//这里的file与上边的formdata.append的键值相对应
var file = req.body.file
//过滤data:URL
var base64Data = file.replace(/^data:image\/\w+;base64,/, "")
var dataBuffer = Buffer.from(base64Data, 'base64')
fs.writeFile("测试.png", dataBuffer, function(err) {
if(err){
res.send({err:-1,msg:err})
}else{
res.send({err:0,msg:"保存成功!"})
}
});
})
总结
cropper.js的难点实际上就是转换为blob文件对象来上传给后端,其他的都是调用人家写好的方法。
这周的分享就到这里了,下周继续努力吧!!!