前天写完文件上传的时候,老板给了个任务,问我能不能把图片压缩后再上传,并且保证前面的功能能正常使用。虽然最后放弃了这个想法,但我在查资料的过程中看到了canvas的toDataURL这个功能。于是就想能不能做一个在线的图片转换器。在经过一天的辛苦耕耘后(我是不会告诉你们我在事件绑定上浪费了半天时间( ´艸`)ムププ),总算弄出个大概了。虽然还有一些东西不太明白,但总体没什么问题了。
主要的几个功能就是:
1.toDataURL(用来压缩转码)
2.通过后台的临时储存来达到跨域获取图片(虽然html5提供了跨域获取图片的方式,但这要你情我愿才行啊(´・ω・`) )
3.js下载图片
有关html5图片跨域可以参考这篇文章:https://developer.mozilla.org/en-US/docs/Web/HTML/CORS_enabled_image
感谢下面的文章提供的学习方向:
http://www.baidufe.com/item/65c055482d26ec59e27e.html
http://blog.csdn.net/chaojie2009/article/details/22047871
首先
HTML:
<!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:
style.css
/*************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.css
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:
//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)♪