热门标签 | HotTags
当前位置:  开发笔记 > 编程语言 > 正文

HTML5和JS实现本地图片裁剪并上传功能-

这篇文章主要为大家详细介绍了HTML5本地图片裁剪并上传的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下
这篇文章主要为大家详细介绍了HTML5本地图片裁剪并上传的相关资料,具有一定的参考价值,感兴趣的小伙伴们可以参考一下

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

要完成上述功能,涉及到的知识有: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代码

预览

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的运行结果如下:

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 = $('

你的浏览器不支持自定义头像,可更换高版本的浏览器自定义头像

'); $('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 === &#39;function&#39;){
  this.callback = callback;
 }
 if(this.__isSupport()){
  chooseFile = boxElem.find(&#39;input[type="file"]&#39;);
  chooseFile
   .on(&#39;change&#39;,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 !== &#39;image/png&#39; && type !== &#39;image/jpg&#39; && type !== &#39;image/jpeg&#39;){
  alert(&#39;文件格式不正确&#39;);
  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(&#39;#preview&#39;);
 img = preView.find(&#39;#preImg&#39;);
 me = this;
 if(img.length <= 0){
  preView.append($(&#39;&#39;));
 }
 img = preView.find(&#39;#preImg&#39;);
 //确保图片加载完成后再执行回调
 img.on(&#39;load&#39;,function () {
  if(me.callback){
   me.callback(me.type);
  }
 });
 img.attr(&#39;src&#39;,reader.result);
};
/**
 * 是否支持预览
 * @returns {boolean}
 * @private
 */
Preview.prototype.__isSupport = function () {
 return typeof FileReader === &#39;function&#39;;
};
var preview = new Preview();
module.exports = preview;

shear.js

var $ = require(&#39;jquery&#39;);
//由于要使用jquery-ui,所以将$暴露到window上。
window.$ = $;
require(&#39;./jquery-ui.min.js&#39;);
/**
 * 切割
 * @constructor
 */
function Shear() {
 this.previewBox = null;
 this.cvsMove = null;
 this.maxW = 200;
 this.maxH = 200;
 this.thum = null;
 this.fileType = &#39;image/jpeg&#39;;
}
/**
 * 入口
 * @param previewBox 预览元素的父元素
 * @param fileType 裁剪的图片的类型 如:&#39;image/jpg&#39;
 * @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(&#39;#thum&#39;);
 this.cvsMove = this.previewBox.find(&#39;#cvsMove&#39;);
 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(&#39;#preImg&#39;);
 preview = this.previewBox.find(&#39;#preview&#39;);
 naturalH = preImg[0].naturalHeight;
 naturalW = preImg[0].naturalWidth;
 //将canvas显示出来
 this.cvsMove.show();
 //将canvas置于(0,0)
 this.cvsMove
  .css({
   "left":&#39;0&#39;,
   &#39;top&#39;:&#39;0&#39;
  });
 h = preImg.height();
 w = preImg.width();
 //规定裁剪出的图片尺寸为200px*200px
 //要保证裁剪的图片不变形
 if(h 

ajax.js

var $ = require(&#39;jquery&#39;);
function Ajax() {

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

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

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

webpack的配置文件如下:

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

效果:

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

以上就是本文的全部内容,希望对大家的学习有所帮助,更多相关内容请关注PHP中文网!


推荐阅读
  • 本文介绍了DataTables插件的官方网站以及其基本特点和使用方法,包括分页处理、数据过滤、数据排序、数据类型检测、列宽度自动适应、CSS定制样式、隐藏列等功能。同时还介绍了其易用性、可扩展性和灵活性,以及国际化和动态创建表格的功能。此外,还提供了参数初始化和延迟加载的示例代码。 ... [详细]
  • 本文介绍了前端人员必须知道的三个问题,即前端都做哪些事、前端都需要哪些技术,以及前端的发展阶段。初级阶段包括HTML、CSS、JavaScript和jQuery的基础知识。进阶阶段涵盖了面向对象编程、响应式设计、Ajax、HTML5等新兴技术。高级阶段包括架构基础、模块化开发、预编译和前沿规范等内容。此外,还介绍了一些后端服务,如Node.js。 ... [详细]
  • 本文介绍了如何使用jQuery和AJAX来实现动态更新两个div的方法。通过调用PHP文件并返回JSON字符串,可以将不同的文本分别插入到两个div中,从而实现页面的动态更新。 ... [详细]
  • 本文介绍了Java后台Jsonp处理方法及其应用场景。首先解释了Jsonp是一个非官方的协议,它允许在服务器端通过Script tags返回至客户端,并通过javascript callback的形式实现跨域访问。然后介绍了JSON系统开发方法,它是一种面向数据结构的分析和设计方法,以活动为中心,将一连串的活动顺序组合成一个完整的工作进程。接着给出了一个客户端示例代码,使用了jQuery的ajax方法请求一个Jsonp数据。 ... [详细]
  • 本文介绍了在开发Android新闻App时,搭建本地服务器的步骤。通过使用XAMPP软件,可以一键式搭建起开发环境,包括Apache、MySQL、PHP、PERL。在本地服务器上新建数据库和表,并设置相应的属性。最后,给出了创建new表的SQL语句。这个教程适合初学者参考。 ... [详细]
  • Java实战之电影在线观看系统的实现
    本文介绍了Java实战之电影在线观看系统的实现过程。首先对项目进行了简述,然后展示了系统的效果图。接着介绍了系统的核心代码,包括后台用户管理控制器、电影管理控制器和前台电影控制器。最后对项目的环境配置和使用的技术进行了说明,包括JSP、Spring、SpringMVC、MyBatis、html、css、JavaScript、JQuery、Ajax、layui和maven等。 ... [详细]
  • Voicewo在线语音识别转换jQuery插件的特点和示例
    本文介绍了一款名为Voicewo的在线语音识别转换jQuery插件,该插件具有快速、架构、风格、扩展和兼容等特点,适合在互联网应用中使用。同时还提供了一个快速示例供开发人员参考。 ... [详细]
  • 本文介绍了高校天文共享平台的开发过程中的思考和规划。该平台旨在为高校学生提供天象预报、科普知识、观测活动、图片分享等功能。文章分析了项目的技术栈选择、网站前端布局、业务流程、数据库结构等方面,并总结了项目存在的问题,如前后端未分离、代码混乱等。作者表示希望通过记录和规划,能够理清思路,进一步完善该平台。 ... [详细]
  • 本文介绍了通过ABAP开发往外网发邮件的需求,并提供了配置和代码整理的资料。其中包括了配置SAP邮件服务器的步骤和ABAP写发送邮件代码的过程。通过RZ10配置参数和icm/server_port_1的设定,可以实现向Sap User和外部邮件发送邮件的功能。希望对需要的开发人员有帮助。摘要长度:184字。 ... [详细]
  • 在springmvc框架中,前台ajax调用方法,对图片批量下载,如何弹出提示保存位置选框?Controller方法 ... [详细]
  • 在Android中解析Gson解析json数据是很方便快捷的,可以直接将json数据解析成java对象或者集合。使用Gson解析json成对象时,默认将json里对应字段的值解析到java对象里对应字段的属性里面。然而,当我们自己定义的java对象里的属性名与json里的字段名不一样时,我们可以使用@SerializedName注解来将对象里的属性跟json里字段对应值匹配起来。本文介绍了使用@SerializedName注解解析json数据的方法,并给出了具体的使用示例。 ... [详细]
  • 从零基础到精通的前台学习路线
    随着互联网的发展,前台开发工程师成为市场上非常抢手的人才。本文介绍了从零基础到精通前台开发的学习路线,包括学习HTML、CSS、JavaScript等基础知识和常用工具的使用。通过循序渐进的学习,可以掌握前台开发的基本技能,并有能力找到一份月薪8000以上的工作。 ... [详细]
  • 后台获取视图对应的字符串
    1.帮助类后台获取视图对应的字符串publicclassViewHelper{将View输出为字符串(注:不会执行对应的ac ... [详细]
  • Java验证码——kaptcha的使用配置及样式
    本文介绍了如何使用kaptcha库来实现Java验证码的配置和样式设置,包括pom.xml的依赖配置和web.xml中servlet的配置。 ... [详细]
  • 本文介绍了解决IE678伪类不兼容问题的方法,包括少用CSS3和HTML5独有的属性,使用CSS hacker,使用last-child清除浮动、批量添加标签、去掉list item最后一个的border-right等技巧。同时还介绍了使用after清除浮动时加上IE独有属性zoom:1的处理方法。另外,本文还提到可以使用jQuery代替批量添加标签的功能,以及使用负边距和CSS2选择器element+element去掉list item最后一个的border-right的方法。 ... [详细]
author-avatar
jixiaojia
PHP1.CN | 中国最专业的PHP中文社区 | DevBox开发工具箱 | json解析格式化 |PHP资讯 | PHP教程 | 数据库技术 | 服务器技术 | 前端开发技术 | PHP框架 | 开发工具 | 在线工具
Copyright © 1998 - 2020 PHP1.CN. All Rights Reserved | 京公网安备 11010802041100号 | 京ICP备19059560号-4 | PHP1.CN 第一PHP社区 版权所有