使用cropper.js 实现简单的头像裁剪上传

最近项目中用到了头像上传功能,于是找了好久找到了cropper.js,简单做个小例子,话不多说直接上代码

<!DOCTYPE html>
<html lang="en">

<head>
    <meta charset="utf-8">
    <meta http-equiv="x-ua-compatible" content="ie=edge">
    <meta name="viewport" content="width=device-width, initial-scale=1, shrink-to-fit=no">
    <title>Cropper.js</title>
    <link rel="stylesheet" href="../dist/cropper.css">
    <style>
        .container{
            width:500px;
            height:500px;
            border:1px solid #000;
            float: left;
        }
        .preview{
            width: 200px;
            height: 200px;
            float: left;
            border:1px solid #000;
            margin-left: 100px;
        }
        button{
            width: 100px;
            height: 30px;
            margin-top: 30px;
            margin-left: 150px;
        }
    </style>
</head>

<body>
    <div class="container">
        <input type="file" id="file">
        <img src="" alt="" id="img">
    </div>
    <div class="preview">
         <img src="" alt="" id="imga">
    </div>
    <button>上传图片</button>

    <script src="https://cdn.bootcss.com/jquery/1.12.4/jquery.min.js"></script>
    <script src="../dist/cropper.js"></script>
    <script>
        var image = document.getElementById('img');
        var cropper, canvas;
        $('#file').change(function(e){
            var file;
            var files = e.target.files;
             if (files && files.length > 0) {
                file = URL.createObjectURL(files[0]);
                $('#img').attr({'src': file})
            }
             cropper = new Cropper(image, {
                aspectRatio: 1,
                viewMode: 1,
                background: false,  //是否显示网格背景
                zoomable: false,   //是否允许放大图像
                guides: false,   //是否显示裁剪框虚线
                crop: function (event) { //剪裁框发生变化执行的函数。
                    canvas = cropper.getCroppedCanvas({  //使用canvas绘制一个宽和高200的图片
                        width: 200,
                        height: 200,
                    });
                    $('#imga').attr("src", canvas.toDataURL("image/png", 0.3))  //使用canvas toDataURL方法把图片转换为base64格式
                }
            });
        })

        $('button').click(function () {
            var file = dataURLtoBlob($('#imga').attr("src"));  //将base64格式图片转换为文件形式
            var formData = new FormData();
            var newImg = new Date().getTime() + '.png';   //给图片添加文件名   如果没有文件名会报错
            formData.append('file', file, newImg)  //formData对象添加文件
            $.ajax({
                type: "POST",
                url: url + "/res/upload",
                data: formData,
                processData: false,  // 不处理数据
                contentType: false,  // 不设置内容类型
                success: function (data) {
                    var data = JSON.parse(data);
                }
            })
        })
        

        //将base64格式图片转换为文件形式
        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);
            }
            return new Blob([u8arr], { type: mime });
        }
    </script>
</body>

</html>
说说使用过程中遇到的一些坑,使用cropper.js实例化时候一定要用原生获取如:
var image = document.getElementById('img');
cropper = new Cropper(image, {
aspectRatio: 1,
viewMode: 1,
background: false, //是否显示网格背景
zoomable: false, //是否允许放大图像
guides: false, //是否显示裁剪框虚线
crop: function (event) { //剪裁框发生变化执行的函数。
canvas = cropper.getCroppedCanvas({ //使用canvas绘制一个宽和高200的图片
width: 200,
height: 200,
});
$('#imga').attr("src", canvas.toDataURL("image/png", 0.3)) //使用canvas toDataURL方法把图片转换为base64格式
}
});

因为实例化时候image必须是DOM节点,而jquery获取到的是jquery对象,如果要用jquery会报错。

因为后台不接受base64编码,所以先把base64转换为文件:

//将base64格式图片转换为文件形式
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);
}
return new Blob([u8arr], { type: mime });
}

使用formData对象上传文件,由于转换后的文件没有文件名,如果不添加文件名上传会报错:

var file = dataURLtoBlob($('#imga').attr("src")); //将base64格式图片转换为文件形式
var formData = new FormData();
var newImg = new Date().getTime() + '.png'; //给图片添加文件名 如果没有文件名会报错
formData.append('file', file, newImg) //formData对象添加文件
$.ajax({
type: "POST",
url: url + "/res/upload",
data: formData,
processData: false, // 不处理数据
contentType: false, // 不设置内容类型
success: function (data) {
var data = JSON.parse(data);
}
})

使用ajax上传是注意要把processData,contentType参数设置为false,不然会报错


版权声明:本文为ljt123456765原创文章,遵循 CC 4.0 BY-SA 版权协议,转载请附上原文出处链接和本声明。
本文链接:https://blog.csdn.net/ljt123456765/article/details/79716260

智能推荐

POJ2348 UVa10368 HDU1525 Euclid's Game【博弈】

Euclid's GameTime Limit: 2000/1000 MS (Java/Others)    Memory Limit: 65536/32768 K (Java/Others) Total Submission(s): 4106    Accepted Submission(s): 1947 Probl...

使用Breeze.js编写更好的查询

这篇文章是由同行评审Agbonghama柯林斯 。 感谢所有SitePoint的审稿作出SitePoint内容也可以是最好的! 数据量正在迅速发展,他们正在变得越来越复杂,维护。 许多开发人员希望避免由数据问题他们的工作过程中造成的问题和头痛。 一个使我们的工作更轻松的图书馆是Breeze.js 。 在这篇文章中,我们将讨论我们如何能够写出更好的查询与Breeze.js。 但是首先,我们应该知道什...

Netty框架构建Nio编程

~~~ 随手点赞,养成习惯 ~~~ 为什么选择Netty框架 Netty是业界最流行的NIO框架之一,它的健壮性、功能、性能、可定制性和可扩展性在同类框架中都是首屈一指的。 优点: ① API使用简单,开发门槛低 ②功能强大,预置了多种编解码功能,支持多种主流协议 ③ 定制能力强,可以通过ChannelHandler对通信框架进行灵活地扩展; ④性能高,通过与其他业界主流的NIO框架对比,Nett...

【JZOJ5262】【GDOI2018模拟8.12】树(DP,性质题)

Description Solution 首先我们可以知道两个性质:1、路径u-v和路径v-w可以合并为路径u-w;2、路径u1-v1加路径u2-v2和路径u1-v2加路径u2-v1是等价的(就是起始点和终点可以互换) 那么知道这些性质之后就很好做了。我们只用知道每个点多少次做起点和多少次做终点。 我们设f[i]表示满足i子树的需求i上的值要是多少。 那么枚举i的所有儿子,判断a[i]-f[i],...

【String-easy】541. Reverse String II 反转的元素,有反转个数和间隔

1. 题目原址 https://leetcode.com/problems/reverse-string-ii/ 2. 题目描述 3. 题目大意 给定一个字符串,和字符串的间隔k, 这个k表示每k个数反转一次,然后再间隔k个元素再反转k个元素。 4. 解题思路 只要按照间隔去反转就可以了。然后间隔k个元素不反转是通过让i每次递增 2*k完成的。 5. AC代码 6. 相似题型 【1】344. Re...

猜你喜欢

【C语言笔记结构体】

我们都知道C语言中变量的类型决定了变量存储占用的空间。当我们要使用一个变量保存年龄时可以将其声明为int类型,当我们要使用一个变量保存某一科目的考试成绩时可以将其声明为float。 那么,当我们要做一个学生信息管理系统时,需要保存学生的姓名、学号、年龄等信息,该怎么做呢? 如当要保存三个学生的信息时, 方法一是: 方法二是: 显然,方法二跟更清晰,因为它把name、num、age都集成在一个模板,...

39. Combination Sum 回溯算法简析

LeetCode传送门     这道题要求给你一组正数 C,然后给你一个目标数 T,让你从那组C中找到加在一起等于 T 的那些组合。     例如:给你 [2,3,6,7] 和 7,则返回 [[2,2,3],[7] ] 。      想解决这个问题前,我们首先引入一个新问题,图(树)的遍历问题。  ...

git安装|Linux系统安装 git|Linux如何安装git?Linux通过远程安装git|

Git是一个开源的分布式版本控制系统,可以有效、高速地处理项目版本管理。Git 是 Linus Torvalds 为了帮助管理 Linux 内核开发而开发的一个开放源码的版本控制软件。 开发者需要一个GIT账号,通过这个查看项目的提交记录,可以更加清楚项目的开发情况,便于版本控制。 以下介绍在CentOS8操作系统搭建GIT服务器。   一、安装GIT服务器流程   安装GIT...

Vue框架基础概要

  Vue.js是什么? Vue.js(读音 /vjuː/,类似于 view 的读音)是一套构建用户界面(user interface)的渐进式框架。与其他重量级框架不同的是,Vue 从根本上采用最小成本、渐进增量(incrementally adoptable)的设计。Vue 的核心库只专注于视图层,并且很容易与其他第三方库或现有项目集成。另一方面,当与单文件组件和...