最近做了一个项目,这个项目中需要实现的一个功能是:用户自定义头像(用户在本地选择一张图片,在本地将图片裁剪成满足系统要求尺寸的大小)。这个功能的需求是:头像最初剪切为一个正方形。如果选择的图片小于规定的头像要求尺寸,那么这整张图片都会作为头像。如果大于规定的尺寸,那么用户可以选择要裁剪的区域。用户点击确定按钮,就将裁剪得到的图片数据发送到服务器,在后端将图片数据保存成一个文件。

要完成上述功能,涉及到的知识有:ajax,canvas和html5中的files接口。我将实现这个功能的代码封装到了4个模块中,分别是ajax.js,preview.js,shear.js和customerImg.js。

ajax.js:用于发送ajax请求。

preview.js:用于图片预览

shear.js:用于裁剪图片

customer.js:自定义头像。在这个模块中药引入ajax.js,preview.js和shear.js

我使用webpack进行打包。我还使用了jquery和jquery-ui。

我从这个项目中抽离出了这个功能。下面是这个功能的详细代码。

1.HTML代码

<div class="m-warp" id="warp"><div class="item"><input type="file" name="img" id="img" hidden><label for="img">选择图片</label></div><div class="item clearfix"><div class="col col-1"><div class="preview" id="preview"><div class="mask"></div><canvas class="cvsMove" id="cvsMove"></canvas></div></div><div class="thum col-2 col"><p>预览</p><img src="" id="thum"><p class="f-text-l f-marTop-20"><button class="shear" id="submit">确定</button></p></div></div></div>

2.CSS代码

.clearfix:after{content: "";display: block;clear: both;height: 0;overflow: hidden;visibility: hidden;
}
img{  vertical-align: middle;  max-width:100%}
.m-warp{width: 800px;
}
.item{margin-top: 20px;
}
.col{float: left;
}
.col-1{position: relative;width: 450px;height: 450px;outline: 1px solid #333;
}
.preview{display: inline-block;
}
.col-2{width: 300px;margin-left: 50px;
}
label{display: block;text-align: center;width: 100px;font-size: 16px;color: #fff;background-color: #888888;height: 30px;line-height: 30px;
}
.mask{position: absolute;z-index: 1;top:0;left: 0;bottom: 0;right: 0;background-color: rgba(0,0,0,.4);
}
.cvsMove{position: absolute;z-index: 2;outline: 2px dotted #333;cursor: move;display: none;
}

有了css和html的运行结果如下:

3.js代码

customerImg.js

var $ = require('jquery');
var ajax = require('./ajax.js');
var preview = require('./preview.js');
var shear = require('./shear.js');
/*** 自定义头像* @constructor*/
function CustomerImg() {this.isSupport = null;this.previewBox = null;this.warp = null;
}
/*** 入口* @param warp 操作区域 jquery节点*/
CustomerImg.prototype.start = function (warp) {var info,me,warpBox;me = this;this.isSupport = this.__isSupport();if(!this.isSupport) {info = $('<p>你的浏览器不支持自定义头像,可更换高版本的浏览器自定义头像</p>');$('body').html(info);return this;}//判断操作区域示范存在if(warp && warp.length > 0){this.warp = warp;}else{return this;}//预览
    preview.start(warp,shear.start.bind(shear,warp));this.previewBox = warp.find('#preview');//确定
    warp.find('#submit').unbind('click').on('click',me.__submit.bind(me));
};
/*** 提交* @private*/
CustomerImg.prototype.__submit = function () {var cvsMove,data,fd;cvsMove = this.previewBox.find('#cvsMove');data = cvsMove[0].toDataURL('image/jpg',1);fd = {'customerImg':data};ajax.upload(fd);
};
/*** 判断是否支持自定义头像* @returns {boolean}* @private*/
CustomerImg.prototype.__isSupport = function () {var canvas,context;canvas= document.createElement('canvas');if(typeof FileReader === 'function'&& canvas.getContext && canvas.toDataURL){return true;}else{return false;}
};
var customerImg = new CustomerImg();
module.exports = customerImg;

preview.js

/*** Created by star on 2017/3/7.*/
var $ = require('jquery');
/*** 预览类* @constructor*/
function Preview() {this.boxElem = null;this.callback = null;this.type = null;
}
/*** 入口* @param boxElem 操作区域* @param callback 预览结束的回调函数*/
Preview.prototype.start = function (boxElem,callback) {var chooseFile,me;me = this;if(! boxElem || boxElem.length <= 0) return this;this.boxElem = boxElem;if(typeof callback === 'function'){this.callback = callback;}if(this.__isSupport()){chooseFile = boxElem.find('input[type="file"]');chooseFile.on('change',me.fileChange.bind(me))}
};
/*** 选择图片的事件处理程序* @param event*/
Preview.prototype.fileChange = function (event) {var target,reader,file,me,type;target =  event.target;me = this;file = target.files[0];type = file.type;this.type = type;if(type !== 'image/png' && type !== 'image/jpg' && type !== 'image/jpeg'){alert('文件格式不正确');return this;}reader = new FileReader();if(file){reader.readAsDataURL(file);}reader.onload = function () {me.show(reader);}
};
/*** 显示从本地选择的图片* @param reader fileReader对象*/
Preview.prototype.show = function (reader) {var preView,img,me;preView = this.boxElem.find('#preview');img = preView.find('#preImg');me = this;if(img.length <= 0){preView.append($('<img id="preImg">'));}img = preView.find('#preImg');//确保图片加载完成后再执行回调img.on('load',function () {if(me.callback){me.callback(me.type);}});img.attr('src',reader.result);
};
/*** 是否支持预览* @returns {boolean}* @private*/
Preview.prototype.__isSupport = function () {return typeof FileReader === 'function';
};
var preview = new Preview();
module.exports = preview;

shear.js

var $ = require('jquery');
//由于要使用jquery-ui,所以将$暴露到window上。
window.$ = $;
require('./jquery-ui.min.js');
/*** 切割* @constructor*/
function Shear() {this.previewBox = null;this.cvsMove = null;this.maxW = 200;this.maxH = 200;this.thum = null;this.fileType = 'image/jpeg';
}
/*** 入口* @param previewBox 预览元素的父元素* @param fileType 裁剪的图片的类型 如:'image/jpg'* @returns {Shear}*/
Shear.prototype.start = function (previewBox,fileType) {if(!arguments.length) return this;var me = this;this.previewBox = previewBox;if(fileType){this.fileType = fileType;}this.thum = this.previewBox.find('#thum');this.cvsMove = this.previewBox.find('#cvsMove');this.showCanvas();return this;};
/*** 显示出canvas*/
Shear.prototype.showCanvas = function () {var preImg,h,w,me,cvsH,cvsW,rateH,rateW,naturalH,naturalW,preview;me = this;preImg = this.previewBox.find('#preImg');preview = this.previewBox.find('#preview');naturalH = preImg[0].naturalHeight;naturalW = preImg[0].naturalWidth;//将canvas显示出来this.cvsMove.show();//将canvas置于(0,0)this.cvsMove.css({"left":'0','top':'0'});h = preImg.height();w = preImg.width();//规定裁剪出的图片尺寸为200px*200px//要保证裁剪的图片不变形if(h < this.maxH || w < this.maxW){this.cvsMove[0].width = cvsW = Math.min(h,w);this.cvsMove[0].height = cvsH = Math.min(h,w);}else{this.cvsMove[0].width= cvsW = this.maxW;this.cvsMove[0].height= cvsH = this.maxH;}rateH = h/naturalH;rateW = w/naturalW;this.__drawImg(preImg,0,0,cvsW/rateW,cvsH/rateH,0,0,cvsW,cvsH);//使用jquery-ui中的功能使canvas可以移动this.cvsMove.draggable({containment: "parent",drag:function (event,ui) {var left,top;left = ui.position.left;top = ui.position.top;//canvas每次移动都有从新绘制图案me.__drawImg(preImg,left/rateW,top/rateH,cvsW/rateW,cvsH/rateH,0,0,cvsW,cvsH);}})
};
/*** 在canvas上显示图片* @param myImg 要显示的图片节点* @param sx 图片的起点在原图片上的x坐标* @param sy 图片的起点在原图上的y坐标* @param sW 在原图上的宽度* @param sH 在原图上的高度* @param dx 起点在canvas上的x坐标* @param dy 起点在canvas上的y坐标* @param dW 在canvas上的宽度* @param dH 在canvas上的高度* @private*/
Shear.prototype.__drawImg = function (myImg,sx,sy,sW,sH,dx,dy,dW,dH) {var cxt,thum,me;me = this;cxt = this.cvsMove[0].getContext('2d');cxt.drawImage(myImg[0],sx,sy,sW,sH,dx,dy,dW,dH);thum = this.thum;//将canvas上的图案显示到右侧
    thum.attr('src',this.cvsMove[0].toDataURL(me.fileType,1)).width(this.maxW).height(this.maxH)
};
var shear = new Shear();
module.exports = shear;

ajax.js

var $ = require('jquery');
function Ajax() {}
/*** 上传图片数据*/
Ajax.prototype.upload = function (data) {$.ajax({type:'POST',data:data,dataType:'json',url:'/test/PHP/upload.php',success:function (result) {if(result.status){location.reload();}else{alert(result.msg);}}});
};
var ajax = new Ajax();
module.exports = ajax;

最后在另一个文件中,调用customerImg对象的start方法

var $ = require('jquery');
var customerImg =require('./customerImg.js');
customerImg.start($('#warp'));

webpack的配置文件如下:

var webpack = require('webpack');
module.exports = {entry:{'customerImg':'./js/test.js','jQuery':['jquery']},output:{filename:'[name].js',library:'jQuery',libraryTarget:'umd'},plugins:[new webpack.optimize.CommonsChunkPlugin({name:'jQuery',filename:'jquery.js'})]
};

效果:

4.php代码

if(!empty($_POST) && isset($_POST['customerImg'])){$img = $_POST['customerImg'];$imgdata = explode(',', $img);$uniName = md5 ( uniqid ( microtime ( true ), true ) );$a = file_put_contents('./../uploads/'.$uniName.'.jpg',  base64_decode($imgdata[1]));
}

转载于:https://www.cnblogs.com/QxQstar/p/6607039.html

HTML5本地图片裁剪并上传相关推荐

  1. html上传图片裁剪,基于HTML5+JS实现本地图片裁剪并上传功能

    基于HTML5+JS实现本地图片裁剪并上传功能 2019-01-07 编程之家 https://www.jb51.cc 编程之家收集整理的这篇文章主要介绍了基于HTML5+JS实现本地图片裁剪并上传功 ...

  2. ie js html 压缩,H5图片裁剪-压缩-上传-神奇的Croppie.js

    Croppie.js之图片裁剪压缩上传 h5图片裁剪, 压缩, 上传, 预览是常见功能, 幸运的是我们有cropp.js这款利器. 1. style .actions button, .actions ...

  3. 图片裁剪并上传,电脑手机均实用

    第一步:引入相应的js,这里提供裁剪工具的js,关于我里面引用的hui的前端js您可以去hui.admin的官网下载,资源链接:https://pan.baidu.com/s/1Pt47Fqn1UVj ...

  4. vue实现图片裁剪后上传

    一.背景 目前负责的系统(商城后台管理系统)里面有这么一个需求,为了配合前台的展示,上传的商品图片比较必须是1:1的正方形.(其它地方有时会有5:4或者16:9的需求,但较少).所以需要对上传的图片先 ...

  5. html5 上传图片模板,HTML5实现图片文件异步上传

    ,过现前个能文使近记接的端问对字用近记接 利用HTML5的新特点做文件异步上传非常简单方便,本文主要展示JS部分,html结构.下面的代码并未使用第三发库,如果有参照,请注意一些未展现出来的代码片段. ...

  6. 类似新浪微博和google图片的HTML5实现图片拖拽上传功能

    2019独角兽企业重金招聘Python工程师标准>>> 来源: http://www.lovesunlife.com/?p=315 这篇文章对google图片为蓝本就拖拽上传功能分析 ...

  7. Vue - 实现图片裁剪功能,并上传到服务器(内置第三方最优秀的裁剪图片组件,上传到服务器功能)干净整洁无 BUG 的示例源码与超详细的注释,兼容任意浏览器

    前言 您可以滑动到文章最底部,直接克隆完整示例 Gitee 仓库,与本文教程最终效果一致. 在项目开发中,您难免会遇到图片上传到服务器之前,用户可进行裁剪的需求, 在看了网上大部分教程后,代码都非常乱 ...

  8. 使用富文本编辑器wangEditor完成图片文件的上传

    项目中一些特定的功能可能需要在页面中用到富文本编辑器来实现文件的输入上传等等,在这里用wangEditor来实现使用富文本编辑器进行文件图面的输入和上传保存,这里wangEditor也可以参考wang ...

  9. vue本地上传并预览php,vue.js 实现图片本地预览 裁剪 压缩 上传功能

    以下代码涉及 Vue 2.0 及 ES6 语法. 目标 纯 javascrpit 实现,兼容ie9及以上浏览器,在本地做好文件格式.长宽.大小的检测,减少浏览器交互. 现实是残酷的,为了兼容Ie9 还 ...

最新文章

  1. 命令行带参数启动--命令行相关问题 代码规范
  2. 在Mac上使用pip3安装python的数据统计模块实录
  3. 一九四六年首台电子计算机,2012年计算机一级MsOffice第四十九套练习题及答案解析...
  4. 解决哈希(HASH)冲突的主要方法
  5. 2K17能力值上90的11位球员,你怎么看?
  6. docker镜像制作(二)——构建企业镜像LAMP+BBS
  7. android自定义view生命周期,android基础之自定义view
  8. python线程状态_Python线程
  9. qtreewidgetitem 文字内存太长换行_table文字溢出显示省略号问题
  10. 自己动手简单实现vbb的URL静态化
  11. 针对校园LAN的OpenFlow和软件定义网络
  12. 参加百度开放云编程马拉松后一点总结
  13. 运用freemark引擎的word模板导出
  14. 微信公众号申请、微信支付申请教程
  15. 多元微积分_向量函数偏导
  16. 【Java知识体系】Redis实用教程,深入原理
  17. Android 仿QQ登录动态背景
  18. 设计模式--有道笔记的整理
  19. 深度分析这一年「AI大咖」,最重要的跳槽原因是……
  20. 腾讯的这个框架火了!

热门文章

  1. editplus 快捷键
  2. oledb 操作 excel
  3. GPRS底层API(转)
  4. Android入门逆引手册 - 12 评分条(RatingBar)的使用
  5. ArcGIS Flex API 中的 Flex 技术(一)--事件
  6. 数据结构排序法之希尔排序法(Shell Sort)
  7. 招商银行信用卡中心华泰证券暑期实习软开笔试小结
  8. 游戏提高性能 游戏降帧处理
  9. js list删除指定元素_vue.js
  10. 面试之 Python 进阶