jquery.form + Jcrop + CI框架實(shí)現(xiàn)圖片裁剪上傳

2013-05-08 09:53:28來源:新浪博客作者:聯(lián)ian

功能:

功能:

  • 1.通過jquery.form上傳圖片,并按一定比例顯示預(yù)覽圖。
  • 2.通過Jcrop裁剪圖片,并顯示裁剪預(yù)覽圖
  • 3.通過CI的圖像處理類保存剪切后圖片

問題:

  • 1.通過jquery.form來ajax提交file類的神奇問題
  • 2.獲取ajax加載圖片后圖片尺寸的問題
  • 3.按比例伸縮圖片
  • 4.ajax獲取圖片后綁定Jcrop
  • 5.CI中upload類注意事項(xiàng)
  • 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(){
 //判斷上傳格式,判斷圖片大小好像只能在服務(wù)端檢測(cè),所以預(yù)覽圖片必須先傳上去
 var options = {
success: showResponse,//上傳成功回調(diào)函數(shù)
};
$("#form_photo").ajaxSubmit(options);//ajax上傳圖片,轉(zhuǎn)由CI部分upload_photo
 //方法處理。另外,我上傳file一直沒有成功
 //過jquery.form官方文檔中的submit()中再
 //回調(diào)函數(shù)ajaxForm()的方式,這種方法ajax
 //提交其它表單沒問題
 });
 function showResponse(data){
//根據(jù)返回值判斷上傳是否成功
//成功返回圖片路徑
//jquery添加<img id="jcrop_photo" src="網(wǎng)站目錄"+data />
//jquery添加<img id="preview_photo" src="網(wǎng)站目錄"+data />
//現(xiàn)在開始準(zhǔn)備
init_photo();//初始化jcrop
$("#button_photo").click(function(){ 
 $("#save_photo").submit();//再次上傳剪切后圖片參數(shù)到CI部分save_photo方法 });
 }
 var photo_width = 292;//設(shè)置顯示預(yù)覽圖片的最大尺寸
 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");//反正我是這樣才獲得了真實(shí)的尺寸 
 setTimeout(function(){ //由于圖片加載時(shí)間,可能要通過
//掛起一段時(shí)間后才能讀取圖片尺寸
 if((new_img.height/292) >= (new_img.width/292)){//限定長(zhǎng)或?qū)捵畲鬄?92
$("#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,//剪切預(yù)覽圖 //這時(shí)候圖片的DOM才被獲取,不要在 
onSelect: show_preview, //ready的時(shí)候綁定,也不要jquery添
aspectRatio: 1, //加<img onload="">
 });
 },100);
 }
 function show_preview(coords){ //顯示剪切后圖片預(yù)覽
 if (parseInt(coords.w) > 0){
var i_k = 146 / coords.w; //146為設(shè)置的預(yù)覽圖區(qū)域大小
$("#preview").css({
 "height": (i_k * photo_height) + 'px', //Jcrop官方文檔中給出的是
 "width": (i_k * photo_width) + 'px', //指定的圖片長(zhǎng)寬,這也就是
 "marginLeft": '-' + (i_k * coords.x) + 'px', //為什么要獲得真實(shí)圖片尺寸
 "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')){ //一定要寫表單對(duì)應(yīng)字段
echo 0; //失敗返回給ajax請(qǐng)求0
}else{
$data = $this->upload->data();
echo $data['file_name'];//成功后返回相對(duì)路徑+圖片名

save_photo方法//生產(chǎn)裁剪后圖片
$config['image_library'] = 'gd2';
$config['source_image'] = $_POST['photo_url']; 
$config['new_image'] = './img/user_head/'.'用戶ID'.'.jpg';
$config['maintain_ratio'] = FALSE;//保證設(shè)置的長(zhǎng)寬有效 
$config['x_axis'] = $_POST['p_x']*$_POST['p_k']; //一定要乘以p_k,因?yàn)檫@里存放的
$config['y_axis'] = $_POST['p_y']*$_POST['p_k']; //是原圖而不是瀏覽器上經(jīng)過縮放的
$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{
//裁剪完畢
}

至此已經(jīng)完成圖片上傳并裁剪保存功能,下面圖解一下圖片裁剪原理

jcrop裁剪后預(yù)覽原理

\

注意圖片的邊長(zhǎng)應(yīng)該是上傳圖片大小除以比例K,即p.h/k。這關(guān)系到后來服務(wù)器端裁剪圖片。

c.x,c.y,c.h,c.w等為jcrop提供的參數(shù),分別是裁剪點(diǎn)離原圖片左上角x方向距離,y方向距離,裁剪高度,寬度。

對(duì)于顯示裁剪區(qū)域圖片,首先要把圖片縮放,縮放比例為js代碼中show_preview方法的i_k,然后移動(dòng)位置,將<img>放在<div syle="height:146px;width:146px;overflow:hidden">中,隱藏不必要顯示的部分。

CI裁剪圖片原理

\

$config['x_axis'] :據(jù)圖像左上角x軸距離
$config['y_axis'] :據(jù)圖像左上角y軸距離
$config['width']:裁剪的寬度
$config['height']:裁剪的長(zhǎng)度

所以根據(jù)傳來的數(shù)值,都應(yīng)在相對(duì)的p_x等乘以p_k,即,比如$config['x_axis'] = $_POST['p_x']*$_POST['p_k'];

關(guān)鍵詞:jqueryJcropcodeigniter

贊助商鏈接: