本文主要包含HTML5本地图片裁剪上传,HTML5图片裁剪,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代码
<p class="m-warp" id="warp">
<p class="item">
<input type="file" name="img" id="img" hidden>
<label for="img">选择图片</label>
</p>
<p class="item clearfix">
<p class="col col-1">
<p class="preview" id="preview">
<p class="mask"></p>
<canvas class="cvsMove" id="cvsMove"></canvas>
</p>
</p>
<p 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>
</p>
</p>
</p>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 = pre

