發現經常有人在技術群裡問要PHP圖片上傳裁切並且預覽的例子。今天正好有時間,就親自做了一個,同時把方法公布出來,讓大家可以理解,學會如何用ThinkPHP+jcrop做這個例子。首先先下來jcrop,網址:http://deepliquid.com/content/Jcrop_Download.html
下載完成後,裡面有js,demo,css等檔案夾.demo裡是例子,建議大家先看一下原始碼.剩下的,跟我一起來做這個例子:
1.下載ThinkPHP,然後建立項目,產生項目目錄
2.在Tpl中建立Index/index.html
代碼如下
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>上傳圖片</title> <script> function setFile(f1){ document.frm.logoImg.value=f1; } </script></head><body><table border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td height="45" align="center" valign="middle"> <form action="#" method="post" name="frm"> 請選擇上傳的圖片 <input name="logoImg" id="logoImg" type="text" size="30"/> <label style="cursor:hand" onClick="window.open('__URL__/upimg','上傳圖片','height=600,width=800,top=200,left=200')">上傳圖片</label><br/> </form> </td> </tr></table></body></html>
這是一個上傳,在點擊上傳圖片以後,會彈出一個視窗,專門用來上傳圖片裁切。在Tpl/Index/下建立upimg.html
代碼如下:
<!DOCTYPE HTML PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN""http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=utf-8"><title>上傳圖片</title><script language="javascript"> function $(id){ return document.getElementById(id); } function ok(){ $("logoimg").src = $("filename").value; }</script></head><body><table border="0" align="center" cellpadding="0" cellspacing="0"> <tr> <td height="45" align="center" valign="middle"> <form action="__URL__/uploadf?submit=1" method="post" enctype="multipart/form-data" name="form1"> 請選擇上傳的圖片 <input type="file" name="filename" id="filename" onchange="ok()"> <!-- MAX_FILE_SIZE must precede the file input field --> <input type="hidden" name="MAX_FILE_SIZE" value="30000" /> <input type="submit" name="Submit" value="上傳"> </form> </td> </tr></table></body></html>
我沒有用TP內建的檔案上傳類,如果大家需要,可以改下,以上主要就是彈出一個上傳檔案的視窗,在這個視窗中會完成檔案上傳,裁切等操作。點擊提交到Index/uploadf
Index/uploadf代碼如下:
$path = "uploadfiles/"; //圖片上傳地址 if (! file_exists ( $path )) { mkdir ( "$path", 0700 ); } $tp = array ( "image/gif", "image/jpeg", "image/png", "image/jpg" ); if (! in_array ( $_FILES ["filename"] ["type"], $tp )) { echo "格式不對"; exit (); } // END IF if ($_FILES ["filename"] ["name"]) { $file1 = $_FILES ["filename"] ["name"]; $file2 = $path . time () . $file1; $flag = 1; } if ($flag) $result = move_uploaded_file ( $_FILES ["filename"] ["tmp_name"], $file2 ); if ($result) { $this->assign('filename',$file2); $this->display(); }
上傳完成以後會直接跳轉到uploadf.html
<!DOCTYPE html PUBLIC "-//W3C//DTD HTML 4.01 Transitional//EN" "http://www.w3.org/TR/html4/loose.dtd"><html><head><meta http-equiv="Content-Type" content="text/html; charset=UTF-8"><title>Insert title here</title></head><script src="__STYLE__/js/jquery.min.js"></script><script src="__STYLE__/js/jquery.Jcrop.js"></script><link rel="stylesheet" href="__STYLE__/css/main.css" type="text/css" /><link rel="stylesheet" href="__STYLE__/css/demos.css" type="text/css" /><link rel="stylesheet" href="__STYLE__/css/jquery.Jcrop.css" type="text/css" /><script language='javascript'> jQuery(function($) { var jcrop_api, boundx, boundy, $preview = $('#preview-pane'), $pcnt = $('#preview-pane .preview-container'), $pimg = $('#preview-pane .preview-container img'), xsize = $pcnt.width(), ysize = $pcnt.height(); console.log('init', [ xsize, ysize ]); $('#target').Jcrop({ onChange : updatePreview, onSelect : updatePreview, aspectRatio : xsize / ysize }, function() { var bounds = this.getBounds(); boundx = bounds[0]; boundy = bounds[1]; jcrop_api = this; $preview.appendTo(jcrop_api.ui.holder); }); function updatePreview(c) { if (parseInt(c.w) > 0) { var rx = xsize / c.w; var ry = ysize / c.h; $pimg.css({ width : Math.round(rx * boundx) + 'px', height : Math.round(ry * boundy) + 'px', marginLeft : '-' + Math.round(rx * c.x) + 'px', marginTop : '-' + Math.round(ry * c.y) + 'px' }); $('#x').val(c.x); $('#y').val(c.y); $('#w').val(c.w); $('#h').val(c.h); } } ; function updateCoords(c){ }; });</script><style type="text/css">.jcrop-holder #preview-pane { display: block; position: absolute; z-index: 2000; top: 10px; right: -240px; padding: 6px; border: 1px rgba(0, 0, 0, .4) solid; background-color: white; -webkit-border-radius: 6px; -moz-border-radius: 6px; border-radius: 6px; -webkit-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2); -moz-box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2); box-shadow: 1px 1px 5px 2px rgba(0, 0, 0, 0.2);}#preview-pane .preview-container { width: 170px; height: 250px; overflow: hidden;}</style><body> <div class="container"> <div class="row"> <div class="span12"> <div class="jc-demo-box"> <img src="__ROOT__/{$filename}" id="target" alt="[Jcrop Example]" /> <div id="preview-pane"> <div class="preview-container"> <img src="__ROOT__/{$filename}" class="jcrop-preview" alt="Preview" /> </div> </div> <div class="clearfix"></div> </div> </div> </div> </div> <form action="__URL__/uploadf?submit=cut" method="post" onsubmit="return checkCoords();"> <input type="hidden" id="x" name="x" /> <input type="hidden" id="y" name="y" /> <input type="hidden" id="w" name="w" /> <input type="hidden" id="h" name="h" /> <input type="hidden" name="filename" value="{$filename}"> <input type="submit" value="Crop Image" /> </form> <!-- <img src="__ROOT__/{$filename}" alt="" /> --></body></html>
這裡的代碼比較長,慢慢解釋吧,我直接複製的jcrop demo裡的tutorial3.html,載入他自己需要的js,css。其中
#preview-pane .preview-container { width: 170px; height: 250px; overflow: hidden;}
這部分CSS會影響到出來的裁切框的比例。以及預覽處的大小。
$('#target').Jcrop({ onChange : updatePreview, onSelect : updatePreview, aspectRatio : xsize / ysize }, function() { var bounds = this.getBounds(); boundx = bounds[0]; boundy = bounds[1]; jcrop_api = this; $preview.appendTo(jcrop_api.ui.holder); });
onChange和onSelect處的意思是裁切的時候要執行的js代碼,說實話,我js和jq的水平很垃圾。所以不管了。
function updatePreview(c) { if (parseInt(c.w) > 0) { var rx = xsize / c.w; var ry = ysize / c.h; $pimg.css({ width : Math.round(rx * boundx) + 'px', height : Math.round(ry * boundy) + 'px', marginLeft : '-' + Math.round(rx * c.x) + 'px', marginTop : '-' + Math.round(ry * c.y) + 'px' }); $('#x').val(c.x); $('#y').val(c.y); $('#w').val(c.w); $('#h').val(c.h); } } ;
這個後面我自己加了一個賦值,賦值給form表單中。然後在提交到php完成裁切工作
點擊提交到uploadf中,可以自己先寫一個圖片裁切的類:
<?phpclass Imgshot { private $filename; private $ext; private $x; private $y; private $x1; private $y1; private $width = 170; private $height = 250; private $jpeg_quality = 90; /** * 構造器 */ public function __construct() {// log_message ( 'debug', "Img_shot Class Initialized" ); } /** * 初始化對象 * * @param * filename 源檔案路徑全明 * @param * width 的寬 * @param * height 的高 * @param * x 橫座標1 * @param * y 縱座標1 * @param * x1 橫座標1 * @param * y1 橫座標2 * */ public function initialize($filename, $x, $y, $x1, $y1) { if (file_exists ( $filename )) { $this->filename = $filename; $pathinfo = pathinfo ( $filename ); $this->ext = $pathinfo ['extension']; } else { $e = new Exception ( 'the file is not exists!', 1050 ); throw $e; } $this->x = $x; $this->y = $y; $this->x1 = $x1; $this->y1 = $y1; } /** * 產生 * 根據圖片的格式,產生不同的 */ public function generate_shot() { switch ($this->ext) { case 'jpg' : return $this->generate_jpg (); break; case 'png' : return $this->generate_png (); break; case 'gif' : return $this->generate_gif (); break; default : return false; } } /** * 得到產生的的檔案名稱 */ private function get_shot_name() { $pathinfo = pathinfo ( $this->filename ); $fileinfo = explode ( '.', $pathinfo ['basename'] ); $filename = $fileinfo [0] . '_small.' . $this->ext; return 'uploadfiles/'.$filename; } /** * 產生jpg格式的圖片 */ private function generate_jpg() { $shot_name = $this->get_shot_name (); $img_r = imagecreatefromjpeg ( $this->filename ); $dst_r = ImageCreateTrueColor ( $this->width, $this->height ); imagecopyresampled ( $dst_r, $img_r, 0, 0, $this->x, $this->y, $this->width, $this->height, $this->x1, $this->y1 ); imagejpeg ( $dst_r, $shot_name, $this->jpeg_quality ); return $shot_name; } /** * 產生gif格式的圖片 */ private function generate_gif() { $shot_name = $this->get_shot_name (); $img_r = imagecreatefromgif ( $this->filename ); $dst_r = ImageCreateTrueColor ( $this->width, $this->height ); imagecopyresampled ( $dst_r, $img_r, 0, 0, $this->x, $this->y, $this->width, $this->height, $this->x1, $this->y1 ); imagegif ( $dst_r, $shot_name ); return $shot_name; } /** * 產生png格式的圖片 */ private function generate_png() { $shot_name = $this->get_shot_name (); $img_r = imagecreatefrompng ( $this->filename ); $dst_r = ImageCreateTrueColor ( $this->width, $this->height ); imagecopyresampled ( $dst_r, $img_r, 0, 0, $this->x, $this->y, $this->width, $this->height, $this->x1, $this->y1 ); imagepng ( $dst_r, $shot_name ); return $shot_name; }}?>
這個是我在網上down的.~沒自己寫,自己可以根據需求擴充一下.
裁切操作:
$filename=$this->cut(); echo "<script language='javascript'>"; echo "alert(\"上傳成功!\");"; echo "</script>"; echo ("<input type=\"button\" name=\"Submit\" value=\"確定\" onClick=\"window.opener.setFile('" .$filename. "');window.close();\">"); echo '<img src="'.__ROOT__.'/'.$filename.'" alt="" />';//裁切的方法 function cut(){ import('ORG.Net.Imgshot'); $imgshot=new Imgshot(); $imgshot->initialize(SITE_PATH.'/'.$_REQUEST['filename'], $_REQUEST['x'], $_REQUEST['y'], $_REQUEST['x']+$_REQUEST['w'], $_REQUEST['y']+$_REQUEST['h']); $filename=$imgshot->generate_shot(); return $filename; }
完成以後會直接echo出最後裁切的圖片,並且還有一個確定按鈕,點擊確定以後,則會把裁切後映像的地址返回到最一開始的input[type="text"]。整個例子我還沒有完善,大家可以根據需要自己去理解和完善。好了,如果不會的朋友可以加群:252799167問我。整個例子我已經發布到ThinkPHP的官網,大家可以下載。
http://www.thinkphp.cn/topic/9154.html
本文出自 “尛雷” 部落格,請務必保留此出處http://a3147972.blog.51cto.com/2366547/1336561