功能:
- 1.通过jquery.form上传图片,并按一定比例显示预览图。
- 2.通过Jcrop裁剪图片,并显示裁剪预览图
- 3.通过CI的图像处理类保存剪切后图片
问题:
- 1.通过jquery.form来ajax提交file类的神奇问题
- 2.获取ajax加载图片后图片尺寸的问题
- 3.按比例伸缩图片
- 4.ajax获取图片后绑定Jcrop
- 5.CI中upload类注意事项
- 6.图片裁剪原理
html页面代码:
<script src="jquery-1.8.3.min.js"></script>
<link rel="stylesheet" href="jquery.Jcrop.css">
<script src="jquery.Jcrop.js"></script>
<script src="jquery.form.js"></script>
<script src="crop_photo.js"></script>
<form id="form_photo" action="example/upload_photo" enctype="multipart/form-data" accept-charset="utf-8" method="post">
头像:<input id="photo_src" type="file" name="photo_src"/>
</form>
<form id="save_photo" action="example/save_photo" accept-charset="utf-8" method="post">
<input type="hidden" name="p_x" id="p_x" value="">
<input type="hidden" name="p_y" id="p_y" value="">
<input type="hidden" name="p_h" id="p_h" value="">
<input type="hidden" name="p_w" id="p_w" value="">
<input type="hidden" name="p_k" id="p_k" value="">
</form>
<input id="button_photo" type="button" value="上传" />
crop_photo.js代码:
//首先是保证jquery.form能ajax提交图片
!function($){
$(function(){
$("#form_photo").ajaxForm();//ajaxForm()只是绑定表单事件,并不是提交表单。。。
$("#button_photo").click(function(){
//判断上传格式,判断图片大小好像只能在服务端检测,所以预览图片必须先传上去
var options = {
success: showResponse,//上传成功回调函数
};
$("#form_photo").ajaxSubmit(options);//ajax上传图片,转由CI部分upload_photo
//方法处理。另外,我上传file一直没有成功
//过jquery.form官方文档中的submit()中再
//回调函数ajaxForm()的方式,这种方法ajax
//提交其它表单没问题
});
function showResponse(data){
//根据返回值判断上传是否成功
//成功返回图片路径
//jquery添加<img id="jcrop_photo" src="网站目录"+data />
//jquery添加<img id="preview_photo" src="网站目录"+data />
//现在开始准备
init_photo();//初始化jcrop
$("#button_photo").click(function(){
$("#save_photo").submit();//再次上传剪切后图片参数到CI部分save_photo方法 });
}
var photo_width = 292;//设置显示预览图片的最大尺寸
var photo_height = 292;
function init_photo(){
var k = 0;//记录图片伸缩比例
var screen_img = $("#jcrop_photo");//通过new_img获取ajax加载的图片
var new_img = new Image(); //直接获取ajax加载图片的尺寸有问题
new_img.src = screen_img.attr("src");//反正我是这样才获得了真实的尺寸
setTimeout(function(){ //由于图片加载时间,可能要通过
//挂起一段时间后才能读取图片尺寸
if((new_img.height/292) >= (new_img.width/292)){//限定长或宽最大为292
$("#jcrop_photo").css("height",292);
photo_width = Math.round(new_img.width*292/new_img.height);
$("#jcrop_photo").css("width",photo_width);
k = new_img.height/292;
}else{
$("#jcrop_photo").css("width",292);
photo_height = Math.round(new_img.height*292/new_img.width);
$("#jcrop_photo").css("height",photo_height);
k = new_img.width/292;
}
$("#p_k").val(k); //将伸缩比例传给hidden表单
$('#jcrop_photo').Jcrop({//绑定Jcrop到图片,必须在此刻绑定
onChange: show_preview,//剪切预览图 //这时候图片的DOM才被获取,不要在
onSelect: show_preview, //ready的时候绑定,也不要jquery添
aspectRatio: 1, //加<img onload="">
});
},100);
}
function show_preview(coords){ //显示剪切后图片预览
if (parseInt(coords.w) > 0){
var i_k = 146 / coords.w; //146为设置的预览图区域大小
$("#preview").css({
"height": (i_k * photo_height) + 'px', //Jcrop官方文档中给出的是
"width": (i_k * photo_width) + 'px', //指定的图片长宽,这也就是
"marginLeft": '-' + (i_k * coords.x) + 'px', //为什么要获得真实图片尺寸
"marginTop": '-' + (i_k * coords.y) + 'px',//的原因,具体图片原理见后文
}).show();
$("#p_x").val(coords.x);//将剪切位置传给hidden表单
$("#p_y").val(coords.y);
$("#p_h").val(coords.h);
$("#p_w").val(coords.w);
}
}
});
}(window.jQuery)
php代码
upload_photo方法 //ajax上传图片
$config['upload_path'] = './img/user_head';
$config['allowed_types'] = 'gif|jpg|png';
$config['max_size'] = '4096';
$config['encrypt_name'] = true;
$this->load->library('upload', $config);//加载upload类
if(!$this->upload->do_upload('photo_src')){ //一定要写表单对应字段
echo 0; //失败返回给ajax请求0
}else{
$data = $this->upload->data();
echo $data['file_name'];//成功后返回相对路径+图片名
}
save_photo方法//生产裁剪后图片
$config['image_library'] = 'gd2';
$config['source_image'] = $_POST['photo_url'];
$config['new_image'] = './img/user_head/'.'用户ID'.'.jpg';
$config['maintain_ratio'] = FALSE;//保证设置的长宽有效
$config['x_axis'] = $_POST['p_x']*$_POST['p_k']; //一定要乘以p_k,因为这里存放的
$config['y_axis'] = $_POST['p_y']*$_POST['p_k']; //是原图而不是浏览器上经过缩放的
$config['width'] = $_POST['p_w']*$_POST['p_k'];//的图
$config['height'] = $_POST['p_h']*$_POST['p_k'];
//$this->load->library('image_lib', $config);
if ( ! $this->image_lib->crop())
{
echo $this->image_lib->display_errors();
}else{
//裁剪完毕
}
至此已经完成图片上传并裁剪保存功能,下面图解一下图片裁剪原理
jcrop裁剪后预览原理
注意图片的边长应该是上传图片大小除以比例K,即p.h/k。这关系到后来服务器端裁剪图片。
c.x,c.y,c.h,c.w等为jcrop提供的参数,分别是裁剪点离原图片左上角x方向距离,y方向距离,裁剪高度,宽度。
对于显示裁剪区域图片,首先要把图片缩放,缩放比例为js代码中show_preview方法的i_k,然后移动位置,将<img>放在<div syle="height:146px;width:146px;overflow:hidden">中,隐藏不必要显示的部分。
CI裁剪图片原理
$config['x_axis'] :据图像左上角x轴距离
$config['y_axis'] :据图像左上角y轴距离
$config['width']:裁剪的宽度
$config['height']:裁剪的长度
所以根据传来的数值,都应在相对的p_x等乘以p_k,即,比如$config['x_axis'] = $_POST['p_x']*$_POST['p_k'];