此时已经取得了裁剪的坐标,只需将坐标传回服务器交给脚本处理
使用jQuery的ajax方法回传数据:
首先是接收上传图片的脚本,接收并存储图片后返回图片数据:
receivePic.php
[php]viewplaincopy
cutPic.php:
整个过程就完成了。上个效果图:
后端的交互很轻松,任务主要在于前端两个插件之间的搭建和使用,我的代码写的比较仓促,应该需要更加结构化一点。另外上传文件的各方面控制也是一个风险(类型,大小等),值得更多的考虑。
----------------------------------------------------------------------------------------------------------------------
一、功能分析
用户直接上传图片,点击"上传"按钮之后,在图片预览图内可预览图片,然后进行图片的裁剪前预览,当点击"裁剪"按钮时确定裁剪图片,并在"裁剪结果"区域显示裁剪后的效果。
(说明:我是将上传文件保存在"/uploads"文件夹中,而截图结果放在"/avatar"文件夹里)
实现效果预览:
二、解决方案
1、插件的选择
jQuery:这个是必备的一个插件可以到官网上下载
imgAreSselect:这个是实现客户端上图片区域选择的
uploadify:实现文件的上传的功能,支持多文件上传,且可定制性非常强。
PIPHP_UploadFile.php:这是一个文件上传功能的php文件
PIPHP_ImageCrop.php:这个php文件是具有对图片进行裁剪的功能
2、客户端与服务器之间的交互图
为了便于理解,我先把交互图放在这里。其中绿色部分是客户端的主要步骤、粉红色是服务器端的主要步骤,服务器与客户端之间的交互通过AJAX完成。可以发现,大部分的操作在客户端进行,服务器端与客户端之间的交流只是简单的JSON数据,因此这样给用户的体验是非常高的。
截图1客户端与服务器之间交互图
3、客户端文件
展示给用户的是html页面,为了学习并巩固CSS知识,就和DIV+CSS搭建了下面这样一个前台页面,见截图2。
截图2前台页面
跟客户端有关的文件主要是一个index.html,而在这个文件里面会引用其他的插件文件,因此可以说,客户端方面只有一个html文件。
另外,由于这里主要讨论客户端与浏览器之间的交互,因此略过CSS方面的内容。这里只列出HTML的代码,首先是部分:
图片剪切上传
可以看得出来主要是引用一些插件的文件。上面的文件(包括CSS文件与js文件)都可以从我给的链接里下载到,只是样式表layout.css是我自己写的样式表,大家可以根据自己的CSS知识写出。
接下来是body部分,也许这么看代码比较乱,推荐使用一些带有高亮显示的工具来查看这些代码,比如DreamWeaver等IDE,实在不行,也可以用火狐的"查看源代码"来看。(火狐不仅是一个好浏览器,更是一个极棒的调试器!)
图片上传
图片预览
裁剪结果:
裁剪预览:
divid="preview">
上面我用颜色区分开主要DIV区,这三块分别代表"上传图片区"、"大图展示区"、"截图结果区"与"选择预览区"。其中三个粗体部分是带有ID属性的空DIV,用来放图片用的。(到时时候动态加载图片到这些DIV中),因此这段代码形成的HTML框架如截图2所示。(蓝色线条是block元素边界,此效果较是由火狐的插件制作而成):
截图3页面大体框架
基本的准备工作已经完成,待会儿再继续在这个框架上添加代码。咱们先介绍一下服务器上的PHP是怎么个情况。
4、服务器文件
服务器上主要用到两个PHP文件,一个用来处理上传图片的process.php,另外一个则是处理图片截图用的crop.php。不过,process.php文件包括插件PIPHP_UploadFile.php,而crop.php中包括PIPHP_ImageCrop.php插件。(这些插件的地址我在上面已经给出了)
=======
process.php主要接收上传图片,设置限制(比如文件的大小与格式),处理一些上传错误等,最后返回给客户端JSON,里面包含了所上传文件的一些信息(比如路径、大小等);当在客户端点击"上传"按钮的时候,会用异步(AJAX)的方式调用这个php文件。
crop.php主要负责真正裁剪上传的图片,当在客户端返回裁剪的位置后(点击"裁剪"按钮后),以异步方式将数据以JSON的方式传递给服务器,crop.php真正裁剪图片后,将图片另存到网络的目录下,同时返回此图片的存储路径,然后再让客户端显示图片即可
三、用到的技术摘要
现在根据上面的交互图继续完善代码。因此我这节会交叉地完善html、js与php代码,并不会单独分开完善,这样在逻辑上会更好理解。
1、uploadify上传
…
type="text/javascript"src="/uploadify/jquery.uploadify.v2.1.4.min.js">
$(document).ready(function(){
//uploadify设置
$('#pic_upload').uploadify({
'uploader':'/uploadify/uploadify.swf',
'script':'process.php',
'cancelImg':'/uploadify/cancel.png',
});
}
2、process.php反馈上传信息
process.php的任务就是给浏览器返回JSON数据(至于什么是JSON请参考其它教程,把JSON想像成"键/值"对就可以了,它很方便数据的传输与读取)。在PHP里,一般是先把数据整理成数组的形式,然后使用json_encode()把数据转换成JSON。那process.php应该给浏览器返回什么样的数据呢?
文件是否成功上传->message
文件的上传状态代码->code
文件上传的存放路径->path
图片的宽度->width
图片的高度->height
图片的缩放比例->scale
图片的名称->name
其中之所以设置图片的缩放比例scale,是因为如果用户上传的图片尺寸太大(比如800x800),浏览器中的DIV会被"撑开",布局会被打乱。因此我们限定在浏览器显示图片的时候任何一边长不能超过400px,否则在显示的时候以等比例缩放。(比如上面的800x800的图上会显示成400x400的,然后浏览器同时设置scale为0.5)。
另外,这个php文件是调用了PIPHP_UploadFile.php这个插件,用来将上传的文件进行"鉴别"与"搬移"。
下面是process.php的程序:
require_once(dirname(__FILE__)."/../PIPHP_UploadFile.php");
$response=array(
'message'=>'未知上传错误',
'path'=>'',
'code'=>-4,//上传结果代码,0表示成功,-1表示失败
'width'=>100,
'height'=>100,
'scale'=>1,//比例尺
'name'=>''
);
if(!empty($_FILES))
{
$name='picture';
$uploadFile='uploads/';
$maxLen=9*1024*1024;
$result=PIPHP_UploadFile($name,$uploadFile,$maxLen);
$response['code']=$result[0];
//简单汇报成功情况
if($result[0]==0)
$response['message']='上传成功!';
//$response['message']=$result[2];
$response['path']=$result[1];
$response['name']=$result[2];
//获取图像的高度与宽度
$fileName=iconv("utf-8","gb2312",$result[2]);
list($width,$height)=getimagesize($_SERVER['DOCUMENT_ROOT'].$uploadFile.$fileName);
$response['width']=$width;
$response['height']=$height;
else
switch($result[0])
case-1:$response['message']="上传失败";break;
case-2:$response['message']="文件类型错误";break;
case-3:$response['message']="文件大小超过限制";break;
default:$response['message']="错误代码:$result[0]";
else{
$response['message']="上传文件出现错误!"."";
$json_str=json_encode($response);
echo$json_str;
>
其实这个程序因为有了if判断语句而显示有点大,其实逻辑还是挺简单的。无论如何,这个程序返回的我上面说的有关图片的上传信息(放在$json_str这变量里了)
3、继续改进uplodify的配置
从上面知道,process.php返回的是一个$json_str变量,它里面有图像的路径,这样我们就可以在浏览器中显示图片啦!(注意此时显示的图片已经是在服务器上了)
现在添加uploadify的'onComplete'选项,它告诉浏览器当process.php返回数据时应该怎么做。
'onComplete':function(event,ID,fileObj,response,data){
json_str=JSON.parse(response);
varmaxSize=400;
varwidth=json_str.width;
varheight=json_str.height;
varscale=json_str.scale;
if(json_str.code==0)
$('#uploadInfo').html(json_str.message+'平均上传速度:'+data.speed.toFixed(2)+'Kb/s');
//对图像进行缩放
if(json_str.width>maxSize||json_str.height>maxSize){
if(json_str.width>json_str.height)
width=maxSize;
height=maxSize/json_str.width*json_str.height;
json_str.scale=maxSize/json_str.width;
height=maxSize;
width=maxSize/json_str.height*json_str.width;
json_str.scale=maxSize/json_str.height;
$('#oriImage').html('');
//同时插入预览图
$('#preview').empty().html('').css({
overflow:'hidden',
width:'150px',
height:'150px'
$('#uploadInfo').html('错误代码['+json_str.code+']:'+json_str.message+'
},
这里的程序主要做两件事,首先(第一种颜色标志处)显示上传的图,不过如果图片太大的话就应该显示缩放后的图,同时将缩放的比例保存到scale变量中;然后(第二处颜色标志处)再初始化裁剪预览图(用jQuery方法),注意这里只是初始化并没有动态显示裁剪预览图,动态显示部分要用imgAreaSelection这个插件完成。下面就开始讲这个插件吧
4、用imgAreaSelection获取截图点坐标
关于imgAreaSelection的使用说明请到官方上查看,这里就不再细讲。
由于图片是动态加载的,所以不能事先将这个插件应用到图像上。我们可以设置一个按钮,当图片上传显示后,我们点击这个"加载裁剪框"按钮,将这个插件绑定到图像上。所以我们先在html上添加一个按钮,我是加载那个"图像预览"的DIV里:
加载裁剪框
//加载裁剪框
$('#initCrop').click(function(e){
ias=$('#oriImageimg').imgAreaSelect({instance:true});
ias.setOptions({aspectRatio:'1:1',handle:true,
hide:false,
onSelectChange:preview2,
onSelectEnd:function(img,selection){
json_str.x1=selection.x1;
json_str.y1=selection.y1;
json_str.cropWidth=selection.x2-selection.x1;
json_str.cropHeight=selection.y2-selection.y1;
这里的onSelectChange选项就是当改变裁剪框时所要调用的函数,这里使用preview2函数名作为值,这个函数我是另外写在下面的,当然你也可以使用匿名函数的。我是为了强调这个函数,所以写成实名函数:
//图像预览函数
functionpreview2(img,selection){
realWidth=json_str.width*json_str.scale;
realHeight=json_str.height*json_str.scale;
sizeWidth=150;sizeHeight=150;
varscaleX=sizeWidth/selection.width;
varscaleY=sizeHeight/selection.height;
$('#previewimg').css({
width:Math.round(scaleX*realWidth)+'px',
height:Math.round(scaleY*realHeight)+'px',
marginLeft:-Math.round(scaleX*selection.x1)+'px',
marginTop:-Math.round(scaleY*selection.y1)+'px'
};
这个函数的功能是实现动态显示截图区域图像的,这个区域大小是150x150像素的一个小框,这里它动态加载css,注意要跟上一节中的uploadify中onComplete中预加载此截图框要联系起来。那里它是这么设置的:
另外的这插件中的onSelectEnd选项配置:当鼠标离开拖选框时,将此裁剪区域的左上角坐标与裁剪区的长、宽存储到json_str变量中,到时候传送给crop.php函数。
5、将json_str数据传送给crop.php
使用jQuery中的ajax()方法将json_str变量传送给服务器。先在html中添加一个"裁剪"按钮:
这里我使用了元素,其实没有必要,可以是任何元素,因为我们使用的是强大的jQuery的ajax()方法。
当用户确定要裁剪时,按下此按钮就会调用ajax()方法。我们将处理程序写在head部分的
//裁剪动作,将数据传给服务器,同时ajax返回图片
$("#crop").click(function(e){
if(!(typeofjson_str=='undefined'))
PHP怎么学习?PHP怎么入门?PHP在哪学?PHP怎么学才快?不用担心,这里为大家提供了PHP速学教程(入门到精通),有需要的小伙伴保存下载就能学习啦!