现在很多网站都需要用户上传头像,而用户电脑里的图片通常不是需求的规格,因此在线图片裁剪功能的需求就诞生了。现代浏览器上很容易实现,但是在IE8上就比较麻烦。首先要接解决图片的本地预览问题,然后再解决操作兼容的问题,最后才是裁剪的问题。
实际上用IE8做纯前端的裁剪是不现实的,最终裁剪的步骤只能交给后端。但是计算坐标,和图片预览在前端可以做到。IE8上可以使FILE控件的一个BUG来取得本地文件的路径。用AlphaImageLoader滤镜来加载本地图片。然后交给用户操作,最后把缩放、坐标等,一些参数和图片一起传到服务器,由服务器来裁剪。
现代浏览器可以用Canvas直接在前端做裁剪,最后生成DataURL的。而且图片的本地预览也有FileReader这个API可以用,所以完全没有难点。但这里的例子为了便于和IE8兼容,整个还是使用了IE8的思路。
这里的服务器端程序用了PHP,裁剪图片用了PHP的GD库。下面是代码:
<?
if($f=$_FILES['f']){
switch($f['type']){
case 'image/png':
case 'image/x-png':
$img=imagecreatefrompng($f['tmp_name']);
break;
case 'image/gif':
$img=imagecreatefromgif($f['tmp_name']);
break;
case 'image/jpeg':
case 'image/pjpeg':
$img=imagecreatefromjpeg($f['tmp_name']);
break;
default:
die('error');
};
extract(array_intersect_key($_POST,array_flip(array('s','x','y','m'))));
$m>0&&$s>0 or die('error');
$new=imagecreatetruecolor($m,$m);
imagefill($new,0,0,imagecolorallocate($new,255,255,255));
imagecopyresampled($new,$img,0,0,$x/$s,$y/$s,$m,$m,$m/$s,$m/$s);
ob_clean();
imagepng($new);
$data=ob_get_clean();
$name=md5($data).'.png';
file_put_contents($name,$data);
header("Location: $name");
die;
};
?>
<style>
#panel {
float:left;
border:1px solid #CCC;
position:relative;
font-size:0px;
overflow:hidden;
user-select:none;
background:#FFF;
text-align:left;
}
#image {
border:1px solid red;
display:inline-block;
visibility:hidden;
transform-origin:left top;
}
#mask {
display:none;
position:absolute;z-index:1;
opacity:0.5;
filter:progid:DXImageTransform.Microsoft.Alpha(opacity=50);
}
#point {
display:none;
border:1px solid #CCC;
margin:-1px;
position:absolute;z-index:1;
cursor:move;
}
#display {
float:left;overflow:hidden;
border:1px solid #CCC;
margin-left:12px;
background:#FFF;
}
</style>
<form target="_blank" method="post" enctype="multipart/form-data">
<div id="panel">
<div id="image"></div>
<div id="mask"></div>
<div id="point"></div>
</div>
<div id="display">
<div id="wrap"></div>
</div>
<input type="file" name="f" />
<input type="hidden" name="s" />
<input type="hidden" name="x" />
<input type="hidden" name="y" />
<input type="hidden" name="m" /><br/>
<input type="submit" value="上传" />
</form>
<script>
onload=function(){
//获取元素
var panel=document.getElementById("panel");
var image=document.getElementById("image");
var mask=document.getElementById("mask");
var point=document.getElementById("point");
var display=document.getElementById("display");
var wrap=document.getElementById("wrap");
var file=document.querySelector("input[type=file]");
var submit=document.querySelector("input[type=submit]");
var form=document.forms[0];
//基本参数初始化
var PANELSIZE=300,DISPLAYSIZE=128;
panel.style.width=PANELSIZE+"px";
panel.style.height=PANELSIZE+"px";
mask.style.border=PANELSIZE+"px solid #CCC";
mask.style.margin=-PANELSIZE+"px";
display.style.width=DISPLAYSIZE+"px";
display.style.height=DISPLAYSIZE+"px";
var pointsize=DISPLAYSIZE,x=0,y=0,mirro;
//提交
submit.onclick=function(){
document.querySelector("input[name=s]").value=mirro.s;
document.querySelector("input[name=x]").value=-parseFloat(wrap.style.marginLeft);
document.querySelector("input[name=y]").value=-parseFloat(wrap.style.marginTop);
document.querySelector("input[name=m]").value=DISPLAYSIZE;
};
//事件操作兼容
var on,off;
if(-[1,])
on=function(e,n,f){e.addEventListener(n,f);},
off=function(e,n,f){e.removeEventListener(n,f);};
else
on=function(e,n,f){e.attachEvent("on"+n,f);},
off=function(e,n,f){e.detachEvent("on"+n,f);};
//选择文件
on(file,"change",function(){
//加载图片文件
if(file.files){
//现代浏览器使用FileReader加载
var reader=new FileReader;
reader.readAsDataURL(file.files[0]);
reader.onload=function(){
var path=reader.result,img=new Image;
img.onload=function(){
image.style.background="url("+path+") no-repeat";
init(img.width,img.height);
},img.src=path;
};
}else{
//低版本IE使用AlphaImageLoader滤镜加载
//无法直接获取到文件的本地路径,只能通过选区(这是个IE的BUG)
file.select(),file.blur(); //不调用blur的话IE9会出错
var path=document.selection.createRange().text;
image.style.filter="progid:DXImageTransform.Microsoft.AlphaImageLoader(src='"+path+"')";
setTimeout(function(){
init(image.offsetWidth-2,image.offsetHeight-2);
},100);
};
//图片加载成功后展示图片
function init(w,h){
if(point.offsetWidth==0){
mask.style.display=point.style.display="block";
x=0,y=0;
};
var m=Math.max(w,h),s=PANELSIZE/m;
image.w=w,image.h=h,image.s=s;
scale(image,s);
image.style.width=w+"px";
image.style.height=h+"px";
image.style.borderWidth="0px";
image.style.visibility="visible";
resize();
};
});
//拖动裁剪区域
on(point,"mousedown",function(e){
var e=e||event;
var px=x-e.clientX,py=y-e.clientY;
var mouseup,mousemove;
on(document,"mouseup",mouseup=function(){
off(document,"mouseup",mouseup);
off(document,"mousemove",mousemove);
}),on(document,"mousemove",mousemove=function(e){
var e=e||event;
move(px+e.clientX,py+e.clientY);
});
});
//滚轮控制裁剪区域缩放
point["onwheel" in point?"onwheel":"onmousewheel"]=function(e){
var e=e||event;
var delta=(e.wheelDelta?e.wheelDelta/-120:e.deltaY/3)*4;
var value=pointsize+delta;
if(value<32||value>PANELSIZE)return;
pointsize=value;
move(x-delta/2,y-delta/2);
resize();
if(e.preventDefault)e.preventDefault();
return false;
};
//其它操作函数定义
function move(ux,uy){
var m=PANELSIZE-pointsize;
x=Math.min(Math.max(ux,0),m);
y=Math.min(Math.max(uy,0),m);
mask.style.left=point.style.left=x+"px";
mask.style.top=point.style.top=y+"px";
var ratio=Math.max(image.w,image.h)*wrap.firstChild.s;
wrap.style.marginLeft=-(wrap.x=ratio*x/PANELSIZE)+"px";
wrap.style.marginTop=-(wrap.y=ratio*y/PANELSIZE)+"px";
};
function resize(){
mask.style.width=mask.style.height=
point.style.width=point.style.height=
pointsize+"px";
mirro=image.cloneNode();
scale(mirro,mirro.s=image.s*DISPLAYSIZE/pointsize);
wrap.innerHTML="";
wrap.appendChild(mirro);
move(x,y);
};
function scale(e,s){
if("zoom" in e.style)e.style.zoom=s;
else
e.style.transform="scale("+s+")",
e.style.marginRight=-e.w*(1-s)+"px",
e.style.marginBottom=-e.h*(1-s)+"px";
};
};
</script>
本文来源于广州网站建设公司与广州网站设计制作公司-广帆互动广州公司!
日期:2015年05月20日
标签: 广州网站设计公司 、 广州网站设计 、 广州网站建设公司 、 广州网站建设 、 广州网站制作公司 、 广州网站制作 、 高端网站设计 、 高端网站建设 、 广州高端网站设计 、 广州高端网站建设