前天寫完文件上傳的時候,老闆給了個任務,問我能不能把圖片壓縮後再上傳,而且保證前面的功能能正常使用。雖然最後放棄了這個想法,但我在查資料的過程當中看到了canvas的toDataURL這個功能。因而就想能不能作一個在線的圖片轉換器。在通過一天的辛苦耕耘後(我是不會告訴大家我在事件綁定上浪費了半天時間( ´艸`)ムププ),總算弄出個大概了。雖然還有一些東西不太明白,但整體沒什麼問題了。
主要的幾個功能就是:
1.toDataURL(用來壓縮轉碼)
2.經過後臺的臨時儲存來達到跨域獲取圖片(雖然html5提供了跨域獲取圖片的方式,但這要你情我願才行啊(´・ω・`) )
3.js下載圖片javascript
有關html5圖片跨域能夠參考這篇文章:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_imagephp
感謝下面的文章提供的學習方向:
http://www.baidufe.com/item/65c055482d26ec59e27e.html
http://blog.csdn.net/chaojie2009/article/details/22047871css
首先
HTML:html5
<!doctype html> <html lang="en"> <head> <meta charset="UTF-8"> <title>IMGFormat</title> <link rel="stylesheet" type="text/css" href="css/style.css"> <link rel="stylesheet" type="text/css" href="css/format.css"> </head> <body> <header id="header">IMGFormat</header> <section id="content"> <section id="con_box"> <div class="img_box"><img src="img/1.jpg" id="source_img"></div> <canvas id="canvas"></canvas> <div class="to">TO</div> <div class="img_box"><img src="img/1.jpg" id="preview_img"></div> <div class="select_box"> <select id="way_choose"> <option selected="selected">本地文件選擇</option> <option>網絡文件選擇</option> </select> <section class="file_choose"> <span>請選擇image文件:</span> <label for="file">+</label> <input type="file" id="file" name="file" accpet="image/*"> </section> <section class="url_input"> <label for="urlGet">請輸入圖片連接:</label> <input type="text" id="urlGet" name="urlGet" placeholder="如:http://www.xx.com/1.jpg"> </section> </div> <div class="tips t1"> 使用連接時請注意圖片是不是外鏈。目前僅支持:jpg|png|gif|bmp </div> <div class="tips t2"> 當圖片較大時,轉png格式可能失敗(做者表示他不知道緣由Σ(゚д゚lll))。 若是有誰知道的話,歡迎在文章下面的評論留言,謝謝。 </div> </section> </section> <footer id="footer"> <span>轉換格式選擇:</span> <ul class="type_list"> <li class="bgAdd">JPG</li> <li>PNG</li> </ul> <label for="quality">圖片質量:</label> <input id="quality" name="quality" type="number" min="10" max="100" step="10" value="50"> <button id="turnTo">轉換</button> <button id="download">下載</button> </footer> <a id="downIMG"></a> <script type="text/javascript" src="js/format.js"></script> </body> </html>
CSS:java
style.csslinux
/*************reset****************/ html{color:#333;-webkit-text-size-adjust:none;height:100%;max-height:100%;overflow: hidden;font-family: 'Microsoft Yahei';} body{height: 100%;max-height:100%;overflow: hidden;} body,div,dl,dt,dd,ul,ol,li,h1,h2,h3,h4,h5,h6,pre,code,form,fieldset,legend,input,button,textarea,p,blockquote,th,td{margin:0;padding:0;} table{border-collapse:collapse;border-spacing:0;} fieldset,img{border:0;} address,caption,cite,code,dfn,em,var,optgroup{font-style:inherit;font-weight:inherit;} del,ins{text-decoration:none;} li{list-style:none;} h1,h2,h3,h4,h5,h6{font-size:100%;}q:before,q:after{content:'';} abbr,acronym{border:0;font-variant:normal;} sup{vertical-align:baseline;} sub{vertical-align:baseline;}legend{color:#000;} input,button,textarea,select,optgroup,option{font-family:inherit;font-size:inherit;font-style:inherit;font-weight:inherit;}input,button,textarea,select{*font-size:100%;} body{font-size:12px;} a{color: #333333;text-decoration: none;} a:hover{text-decoration:underline; color:#c00;} /*font*/ *{ font-size: 1.05em; color: #222; font-family: "Microsoft Yahei"; }
format.cssweb
body{ background: -webkit-linear-gradient(#66ccff,#74b1d1); background: -o-linear-gradient(#66ccff,#74b1d1); background: -moz-linear-gradient(#66ccff,#74b1d1); background: -ms-linear-gradient(#66ccff,#74b1d1); background: linear-gradient(#66ccff,#74b1d1); position: relative; } #header{ height: 2.8em; background: -webkit-linear-gradient(rgba(34,34,34,0.9),rgba(0,0,0,0.7)); background: -o-linear-gradient(rgba(34,34,34,0.9),rgba(0,0,0,0.7)); background: -moz-linear-gradient(rgba(34,34,34,0.9),rgba(0,0,0,0.7)); background: -ms-linear-gradient(rgba(34,34,34,0.9),rgba(0,0,0,0.7)); background: linear-gradient(rgba(34,34,34,0.9),rgba(0,0,0,0.7)); font-size:2.4em; font-weight: bolder; text-align: center; line-height: 2.8em; color: #fff; text-shadow:0 0 0 #eee,0 0 0 #eee,1px 1px 1px #ede,-1px -1px 1px #eee; box-shadow: 0px 2px 6px rgba(16,16,16,0.7); } #content{ position: absolute; top: 10em; left: 0em; bottom: 8em; right: 0em; padding: 0em 2em; } #con_box{ height: 100%; background: #fff; box-shadow:0px 0px 10px rgba(0,0,0,0.9); border: none; border-radius: 10px; padding:0em 8%; position: relative; text-align: center; } .img_box{ width: 100%; max-width: 36%; max-height: 63.4%; height: 100%; display: inline-block; margin-top: 2em; position: relative; } .img_box img{ max-width: 100%; max-height: 100%; width: 100%; height: 100%; vertical-align: middle; } #canvas{ display: none; } .to{ display: inline-block; width: 20%; max-width: 20%; font-size: 3em; font-weight: bolder; } .select_box{ text-align: left; width: 92%; margin:0 auto; margin-top: 2em; } #way_choose{ float: left; margin-right: 2em; } .file_choose,.url_input{ margin: 0 auto; font-weight: bold; font-size:1.4em; text-align: left; display: none; } .file_choose{ display: block; } .file_choose>label{ margin-left: 2em; padding:0 1.2em; font-size: 1.1em; font-weight: bolder; background: #222; color:#fff; } .file_choose>label:hover{ cursor: pointer; box-shadow: 0 0 5px red; } .file_choose>input{ display: none; } .url_input>label{ margin-right: 1em; } .url_input>input{ outline: none; border: 2px solid #dedede; border-radius: 2em; padding-left: 1.5em; width:20em; } .tips{ text-align: left; font-size: 1.2em; font-weight: bold; width: 92%; margin:0 auto; margin-top: 1em; display: none; } .t1{ display: block; } #footer{ position: fixed; bottom: 0em; height: 2.8em; background: #000; line-height: 2.8em; width: 100%; left: 0em; font-size: 1.6em; font-weight: bolder; } #footer>span{ float: left; margin-left:1.5em; } .type_list{ display: inline; margin-right: 2em; } .type_list>li{ display: inline; margin-left: 1em; background: #ffb515; height: 2em; padding:0 0.6em; font-size: 1.05em; color: #fff; text-shadow:-1px 1px 2px rgba(0,0,0,0.7); border-radius:5px; box-shadow:0 0 5px rgba(255,255,255,0.6); } .type_list>li:hover{ cursor: pointer; box-shadow: 0 0 5px rgba(255,0,0,0.7); } #quality{ margin-left: 1em; } #turnTo,#download{ margin-left: 2em; padding: 0 1em; border-radius: 10px; border: 1px solid #d9d9d9; background: -webkit-linear-gradient(#ffffff,#dfdfdf); background: -o-linear-gradient(#ffffff,#dfdfdf); background: -moz-linear-gradient(#ffffff,#dfdfdf); background: linear-gradient(#ffffff,#dfdfdf); box-shadow: 0px 0px 5px rgba(255,255,255,0.7); font-weight: bolder; } #turnTo:hover,#download:hover{ background: -webkit-linear-gradient(#66ccff,#74b1d1); background: -o-linear-gradient(#66ccff,#74b1d1); background: -moz-linear-gradient(#66ccff,#74b1d1); background: -ms-linear-gradient(#66ccff,#74b1d1); background: linear-gradient(#66ccff,#74b1d1); cursor: pointer; border: #6cf 1px solid; } .bgAdd{ background: red !important; }
JS:canvas
//author:孤月 //date:2015/07/17 //變量定義 var sWay = document.getElementById("way_choose"), //獲取獲得圖片連接的方式 sGetUrl = "", //當獲取方式爲連接時,存放獲取的連接地址 sFile = "", //當獲取方式爲本地時,存放獲取的文件信息 sType = "", //獲取要轉換的格式 nQuali = document.getElementById("quality"); //獲取圖片轉換的質量(壓縮比) var urlInput = document.getElementById("urlGet"), file = document.getElementById("file"), sourceImg = document.getElementById("source_img"), previewImg= document.getElementById("preview_img"), canvas = document.getElementById("canvas"), typeList = document.querySelector(".type_list"), turnTo = document.getElementById("turnTo"), download = document.getElementById("download"); var mimeTypeGet, //獲取img格式 canDownload=false, //是否能夠開始下載 cross, //是不是外鏈 go=true; //是否文件或連接或轉換格式改變 //獲取要轉換的目標圖片類型 function getType () { var type; //偵聽click事件 typeList.addEventListener("click",function(e){ e = e || event; if(e.target.tagName.toLowerCase()!="li") return; var val = e.target.innerHTML; var ch = typeList.children; for(var x=0;x<ch.length;x++) ch[x].setAttribute("class",""); e.target.setAttribute("class","bgAdd"); //當目標類型改變時,容許轉換 if(sType!=val.toLowerCase) go = true; sType = val.toLowerCase(); if(sType=="jpg") { document.getElementById("quality").style.display="inline-block"; document.querySelector(".t2").style.display="none"; document.querySelector(".t1").style.display="block"; } else{ document.getElementById("quality").style.display="none"; document.querySelector(".t1").style.display="none"; document.querySelector(".t2").style.display="block"; } },false); } //獲取圖片取得方式 function wayChange(){ //偵聽change事件 sWay.addEventListener("change",function(){ var fc = document.querySelector(".file_choose"), ui = document.querySelector(".url_input"); (sWay.value=="本地文件選擇")?FileShow():UrlShow(); function FileShow(){ fc.style.display = "block"; ui.style.display = "none"; cross = false; }; function UrlShow(){ fc.style.display = "none"; ui.style.display = "block"; cross = true; } turnTo.style.display = "none"; download.style.display="none"; file.value = ""; urlGet.value = ""; },false); } //當文件域變化 function fileChange(){ file.addEventListener("change",function(){ //讀取文件 var files = file.files[0]; var reader = new FileReader(); reader.onload = function(e){ go = true; e = e || event; sourceImg.src = e.target.result; turnTo.style.display = "inline-block"; download.style.display="inline-block"; transformImg(); }; reader.readAsDataURL(files); },false); } //當地址輸入完畢 function urlInputEnd(){ var match; urlInput.addEventListener("blur",function(){ //匹配連接 if(!urlInput.value) return; match = /.jpg|.png|.gif|.bmp/; sGetUrl = urlGet.value; var temp = sGetUrl.substring(sGetUrl.lastIndexOf(".")); if(match.test(temp)) { sourceImg.src = sGetUrl; sourceImg.onload = function(){ go = true; turnTo.style.display = "inline-block"; download.style.display="inline-block"; transformImg(); }; } },false) } //壓縮比變化時 function qualityChange(){ nQuali.onchange = function(e){ //限制取值 var val = e.target.value.toFixed(0); if(!val || val>100 || val<10) nQuali.value = 50; }; } //img下載 function downlo(){ download.onclick = function(){ if(canDownload) { // 加工image data,替換mime type var imgData = previewImg.src.replace(mimeTypeGet,'image/octet-stream'); //download var down = document.getElementById("downIMG"); down.href = imgData; down.download = "IGotIt-"+(new Date()).getTime()+"."+(sType?sType:"jpg"); var mouseEv = document.createEvent("MouseEvents"); mouseEv.initMouseEvent("click",false,false,window,0,0,0,0,0,false,false,false,false,0,null); down.dispatchEvent(mouseEv); } else { alert("請先進行轉換!"); } }; } //轉換 function transformImg(){ turnTo.onclick = function(e){ e = e || event; e.stopPropagation(); e.preventDefault(); var type = sType || "jpg" , mimeType, newImage = new Image(), cv = canvas, ct = cv.getContext('2d'); if(type=="jpg") mimeType = "image/jpeg"; else mimeType = "image/"+type; mimeTypeGet = mimeType; if(cross && go){ //獲取外鏈地址並將其傳入服務器 var xhr = new XMLHttpRequest(); var nForm = new FormData(); nForm.append("url",sourceImg.src); nForm.append("type",sourceImg.src.substring(sourceImg.src.lastIndexOf('.'))); xhr.open('POST','php/send.php'); xhr.send(nForm); xhr.addEventListener("load",function(e){ go = false; var newSrc = e.target.responseText; newImage.src = newSrc; newImage.onload = function(){ previewImg.src=trans().src; nForm.append("del",true); xhr.open("POST",'php/del.php'); xhr.send(nForm); }; },false); } else if(go){ newImage.src = sourceImg.src; previewImg.src=trans().src; } function trans(){ cv.width = newImage.width; cv.height= newImage.height; ct.drawImage(newImage,0,0); if(mimeType=="image/jpeg") var newData = cv.toDataURL(mimeType,nQuali.value/100); else var newData = cv.toDataURL(mimeType); var nImage = new Image(); nImage.src = newData; canDownload = true; downlo(); return nImage; } }; } function init(){ getType(); wayChange(); fileChange(); urlInputEnd(); qualityChange(); } init();
PHP:跨域
send.php
<?php session_start(); if(!$_POST) return false; $dataUrl = trim(mb_convert_encoding($_POST['url'],'gbk','utf-8')); $type = $_POST['type']; $path = "../"; $random = time().rand(1,10000); $dir = "source/".$random."/"; $name = rand(10000,20000).$type; if(!is_dir($path.$dir)) { mkdir($path.$dir); chmod($path.$dir,0777); } $newImageData = @file_get_contents($dataUrl); $createImg = fopen($path.$dir.$name,'w+'); fwrite($createImg,$newImageData); fclose($createImg); $_SESSION['dir'] = $path.$dir; $_SESSION['file']= $name; echo $dir.$name; ?>
del.php
<?php session_start(); if(!$_POST) return false; $del = $_POST['del']; if($del) { @unlink($_SESSION['dir'].$_SESSION['file']); rmdir($_SESSION['dir']); } session_destroy(); ?>
有什麼問題和意見歡迎回復,吐槽樓主的人註定單身一生(o ̄∇ ̄o)♪