首頁 > web前端 > H5教程 > 主體

HTML5和JS實作本機圖片裁切並上傳功能

不言
發布: 2018-06-11 17:34:02
原創
6632 人瀏覽過

這篇文章主要為大家詳細介紹了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(&#39;jquery&#39;);
var ajax = require(&#39;./ajax.js&#39;);
var preview = require(&#39;./preview.js&#39;);
var shear = require(&#39;./shear.js&#39;);
/**
 * 自定义头像
 * @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 = $(&#39;<p>你的浏览器不支持自定义头像,可更换高版本的浏览器自定义头像</p>&#39;);
  $(&#39;body&#39;).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(&#39;#preview&#39;);
 //确定
 warp
  .find(&#39;#submit&#39;)
  .unbind(&#39;click&#39;)
  .on(&#39;click&#39;,me.__submit.bind(me));
};
/**
 * 提交
 * @private
 */
CustomerImg.prototype.__submit = function () {
 var cvsMove,data,fd;
 cvsMove = this.previewBox.find(&#39;#cvsMove&#39;);
 data = cvsMove[0].toDataURL(&#39;image/jpg&#39;,1);
 fd = {
  &#39;customerImg&#39;:data
 };
 ajax.upload(fd);
};
/**
 * 判断是否支持自定义头像
 * @returns {boolean}
 * @private
 */
CustomerImg.prototype.__isSupport = function () {
 var canvas,context;
 canvas= document.createElement(&#39;canvas&#39;);
 if(typeof FileReader === &#39;function&#39;&& 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(&#39;jquery&#39;);
/**
 * 预览类
 * @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;<img id="preImg">&#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 < 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(&#39;2d&#39;);
 cxt.drawImage(myImg[0],sx,sy,sW,sH,dx,dy,dW,dH);
 thum = this.thum;
 //将canvas上的图案显示到右侧
 thum
  .attr(&#39;src&#39;,this.cvsMove[0].toDataURL(me.fileType,1))
  .width(this.maxW)
  .height(this.maxH)
};
var shear = new Shear();
module.exports = shear;
登入後複製

#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;
  })
 ]
};
登入後複製

 效果:

4.php程式碼


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中文網!

相關推薦:

使用HTML5實作網頁音樂播放器


Express使用html範本的程式碼分析


#

以上是HTML5和JS實作本機圖片裁切並上傳功能的詳細內容。更多資訊請關注PHP中文網其他相關文章!

來源:php.cn
本網站聲明
本文內容由網友自願投稿,版權歸原作者所有。本站不承擔相應的法律責任。如發現涉嫌抄襲或侵權的內容,請聯絡admin@php.cn
作者最新文章
熱門教學
更多>
最新下載
更多>
網站特效
網站源碼
網站素材
前端模板