前天写完文件上传的时候,老板给了个任务,问我能不能把图片压缩后再上传,而且保证前面的功能能正常使用。虽然最后放弃了这个想法,但我在查资料的过程当中看到了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)♪