node.js(express)中使用Jcrop进行图片裁切上传

需求说明

简单来说就是要实现用户上传头像,并且要保存用户裁切后的部分作为用户头像。

第一步,选择图片:

第二步,在弹窗页面中展现并进行裁切:

第三步,点击“保存”,上传服务器。

实现过程

说来有点坎坷,相当于做了2遍,走了弯路。

第1遍是用户一选择图片,就进行了上传,然后返回一个地址,所以在弹层上展现的图片已经是服务器上的图片了,然后进行裁切,再保存。

第2遍找到的一个方法,是在第1遍做到裁切处理时候想到的,即弹层展现的是用户机器上选择的图片,不用先上传,但是用image/base64来展现的。这样就与服务器少了一次交互啊,并且服务器不用存储2遍图片,还提高了弹层展现速度,体验更好,所以是极好的。

说下碰到的主要技术点:

  • express框架不用多说,就是保存的时候post一下裁切后的base64数据,后台写个对应路由就好。
  • Jquery也不用多说,页面展现控制与ajax提交。
  • HTML5/FileReader/canvas,FileReader用于将文件读取为数据,我们使用它的onLoad事件;canvas这个用作裁切移动时,实时重绘裁切后的图片(相当于实时预览,当然我是隐藏了,调试的时候可以让他display),可以隐藏,最后上传的其实就是这个canvas的base64数据。
  • Jcrop plugin。这个是裁切插件,必须的了。下载与说明在这里
  • 其他就是base64字符串保存成图片了,这在服务端比较简单,直接用fs.writeFile(fileName,dataBuffer,function(err){});就好了。

具体代码

view页面,主要需要有一个上传控件,还有定义弹窗div以及用于重绘裁切范围图片的canvas,当然页面要引用相应的js插件和css等,主要:

<link rel="stylesheet" href="/css/jquery.Jcrop.css">
<script src="/js/jquery.js"></script>
<script src="/js/jquery.Jcrop.js"></script>

<!--上传控件-->
<input type="file" name="upLoadImg1" id="upLoadImg1">

<!--弹窗与裁切图-->
<div class="cover">
    <img id="Img1" alt="">
    <button id="btnSave">保存</button>
</div>

<!--裁切范围重绘canvas-->
<canvas id="myCanva" width="200" height="200">

js/jquery,处理图片加载与裁切上传。

首先要监控上传控件的变化,因为我们这里没有按钮来触发,所以直接监控upLoadImg1change来触发。

$(‘#upLoadImg1‘).on(‘change‘, function() {
    if (document.getElementById("upLoadImg1").files.length === 0) {
        return;
    }
    var oFile = document.getElementById("upLoadImg1").files[0];
    if (!oFile) {
        return;
    }
    var fileName = oFile.name;
    var fileSize = oFile.size;
    var fileType = fileName.substring(fileName.lastIndexOf(‘.‘), fileName.length).toLowerCase();
    if (fileType != ‘.jpg‘ && fileType != ‘.jpeg‘ && fileType != ‘.gif‘ && fileType != ‘.png‘ && fileType != ‘.bmp‘) {
        alert("请选择jpg,png,gif,bmp格式的图片");
        return;
    }
    if (fileSize > 2 * 1024 * 1024) {
        alert(‘最大支持2MB的图片‘);
        return;
    }
    var fileReader = new FileReader();
    fileReader.readAsDataURL(oFile);

    // 成功读取
    fileReader.onload = function(e) {
        // 显示弹窗
        $(‘.cover‘).show();
        // 将弹窗中的图片路径设置为选择的图片的base64
        $(‘#Img1‘).attr(‘src‘, e.target.result);

        // 裁切组件初始化
        initJcrop();
    };
});

裁切在弹窗一显示的时候就应该初始化:

function initJcrop() {
    $(‘#Img1‘).Jcrop({
        onChange: updateCoords,
        onSelect: updateCoords,
        aspectRatio: 1,
        boxWidth: 300,
        boxHeight: 300
    }, function() {
        //弹窗中显示的图片尺寸
        var bb = this.getBounds();
        var bWidth = Number(bb[0]) / 2;
        var bHeight = Number(bb[1]) / 2;
        //设置初始选中裁切范围
        this.setSelect([0, 0, bWidth, bHeight]);

        //原始图片缩小比例
        try {
            wdthScale = $(‘#Img1‘)["0"].width / 222;
            heightScale = $(‘#Img1‘)["0"].height / 238;
        } catch (e) {}
        jcrop_api = this;
    });
}

非常重要的一个坑是,在此之前要定义全局变量jcrop_api,widthScaleheightScale,2个scale变量用于记录选择的原始图片尺寸与在弹窗上展现尺寸的缩小/放大比例的,比如选择的是1024x768的图片,但是弹窗上展现的范围是222x238,这就需要将缩小的倍数记录下来,在裁切的重绘canvas的时候要乘以这个倍数,否则裁切的范围就是在这个222x236尺寸上裁切的,而不是原始图片的尺寸上裁切的。而前面的jcrop_api变量用于重新选择图片时要将上一次的裁切初始化组件destroy掉。

Jcrop组件中重要的事件:onChange和onSelect,用于确定裁切范围的坐标(尺寸),因此也非常重要,其实重绘canvas就是在这里面完成的。

function updateCoords(c) {
    var img = document.getElementById(‘Img1‘);
    var ctx = document.getElementById(‘myCanva‘).getContext(‘2d‘);
    try {
        wdthScale = wdthScale === 1 ? $(‘#Img1‘)["0"].width / 222 : wdthScale;
        heightScale = heightScale === 1 ? $(‘#Img1‘)["0"].height / 238 : heightScale;
    } catch (e) { }

    //绘制canvas画布
    ctx.drawImage(img, c.x, c.y, c.w * wdthScale, c.h * heightScale, 0, 0, 200, 200);
}

另外就是处理保存按钮来,一个ajax来提交canvas形成的图片的base64字符串,后台接受保存就可以了。

 var data = document.getElementById(‘myCanva‘).toDataURL();
 $.ajax({
     url: ‘/xxxx‘,
     type: ‘POST‘,
     dataType: ‘JSON‘,
     cache: false,
     data: {
         ‘imgData‘: data
     },
     success: function(res) {},
     error: function(err) {}
 });

这就是上传裁切(实时预览)的全部过程了。

时间: 2024-10-20 12:06:20

node.js(express)中使用Jcrop进行图片裁切上传的相关文章

vue+mongoose+node.js项目总结第一篇_图片文件上传

一.前言 项目演示:每个新用户登录之后会有个默认的头像,用户可以根据自己选择自己的头像图片进行更改. 二.主要内容 1.需求实现的思路分析. 第一步:用户点击按钮选择图片其实是间接触发input图片选择 第二步:input表单被监听change事件 第三步:选择图片,然后将图片用canvas画在预览框处 第四步:点击“确定按钮”,请求后端接口配合云存储,将图片上传到云存储上 第五步:利用云存储器中生成的图片url地址替换掉原来的地址 2.具体实现      2.1总体思路  2.2前台实现部分

vue中使用cropperjs进行图片裁剪上传

下面代码直接就可以复制使用了,但是需要在本地下个cropperjs,下载命令:npm install cropperjs --save-dev <template> <div id="yin"> <div id="demo"> <!-- 遮罩层 --> <div class="container" v-show="panel"> <div> <img

【nodejs】--express的中间件multer实现图片文件上传--【XUEBIG】

Multer是nodejs中处理multipart/form-data数据格式(主要用在上传功能中)的中间件.该中间件不处理multipart/form-data数据格式以外的任何形式的数据 Tips:multipart/form-data是用来指定传输数据的特殊类型的,主要就是我们上传的非文本的内容,比如图片或者mp3等等 1.安装第三方插件 cnpm install multer --save 2.配置文件 //引入依赖模块 var express = require('express');

java中使用FTP进行图片的上传

使用ftp需要引入两个jar包(commons-net.commons-fileupload) 1.添加ftp服务器配置文件 #FTP FTP_ADDRESS=192.168.25.133 //目标服务器ip FTP_PORT=21 //ftp默认端口21 FTP_USERNAME=ftpuser //用户名 FTP_PASSWORD=ftpuser //密码 FTP_BASE_PATH=/home/ftpuser/www/images //上传路径 #picServerBaseUrl IMAG

Node.js Express 框架学习

转载:http://JavaScript.ruanyifeng.com/nodejs/express.html#toc0 感觉很牛的样子,不过觉得对初学者没太大用,里面很多例子用的api都没有详细的说明.为了学习备份,所以拷贝过来. Express框架 来自<JavaScript 标准参考教程(alpha)>,by 阮一峰 目录 概述 运行原理 底层:http模块 对http模块的再包装 什么是中间件 use方法 Express的方法 all方法和HTTP动词方法 set方法 response

Nodejs学习笔记(八)--- Node.js + Express 实现上传文件功能(felixge/node-formidable)

目录 前言 formidable简介 创建项目并安装formidable 实现上传功能 运行结果 部分疑惑解析 写在之后 前言 前面讲了一个构建网站的示例,这次在此基础上再说说web的常规功能----文件上传,示例以一个上传图片的功能为例子 上传功能命名用formidable实现,示例很简单! PS:最近比较忙,距上一次更新已经比较久了^_^! formidable简介 nodejs原生实现上传还是比较麻烦,有兴趣的自已去参考一下网上有网友写的代码 这里选择了formidable,也是githu

基于 Node.js + Express + mongoDB + Bootstrap 搭建的电影网站

电影网站 ?? GitHub: https://github.com/bxm0927/movie-website 此项目是基于 Node.js + Express + mongoDB + Bootstrap 搭建的电影网站. 主要功能模块: 一期:前台电影展示页.电影详情页.后台电影管理中心(电影录入.电影修改) 二期:用户登录注册注销功能.用户识别和持久化.后台用户管理中心(用户录入.用户修改).电影评论 <!-- more --> 图片预览 技术栈 [前端] HTML/CSS/JS:亘古不

Node.js Express+Mongodb 项目实战

Node.js Express+Mongodb 项目实战 这是一个简单的商品管理系统的小项目,包含的功能还算挺全的,项目涵盖了登录.注册,图片上传以及对商品进行增.删.查.改等操作,对于新手来说是个很不错的练手项目,分享给大家. GitHub源码:https://github.com/oceanMin/cms 项目前准备 安装node.js 安装express 安装mongoDB 章节目录 快速开始 快速开始 模块 express商品管理系统介绍 框架搭建.ejs .express.static

[Node.js] express 安装的问题

今天学习express的时候发现安装了express模块但是死活不能使用express命令,在windows上提示内部或者外部命令.在Linux上也不能使用,类似的错误信息.在网上找到了解决方案,记录如下: 版本问题,安装的时候使用命令: npm install -g [email protected]   即可解决问题 刚学习node.js,不知道问题的根源是什么?希望知道的大虾解析一下,拜谢.... ==========================华丽的分割线==============