2013年4月13日 星期六

[jcrop+php]學習怎麼做crop image的功能

//這其實是我一個多月前的練習了,突然想到我要記錄一下...

前言:

其實只是我好奇怎麼處理讓別人上傳圖片並且可以讓使用者作切圖的功能,那麼通常這樣的功能,搜尋的關鍵字叫做crop photo或是crop images,為甚麼叫做crop?,藉google翻譯一下才知道crop也有修剪的意思。

然後我就上網找到了一套還不錯的javascript切圖的framework叫做Jcrop
http://deepliquid.com/projects/Jcrop/demos.php
有興趣可以玩玩看,他提供的功能還蠻多的

其實它的原理是,記錄你所裁下的圖片範圍的x,y座標,以及寬(w)跟高(h)


也就是說,當你選了你要裁的區域之後,按下 "我要裁"之類的動作
他會送出一個form,其中就包含4個hidden的value,這四個hidden的value,就是紀錄x,y,w,h的值。


我拿了這套來用,但是要結合一點的PHP
(其實也沒有多複雜,就只是補足我想要的功能而已)
官方的範例雖然有提供到結合php的範例,但是比較不是我想要的部分
因為我還想要把圖存到database去




那,經過的我修改之後,整個資料夾的結構大約如下:
(PS: js資料夾的jquery.min.css打錯了,應該是jquery.min.js)



流程的跑法如下:


(是一個很單純的練習,所以流程很簡單。)

然後我建了一個table
因為我只是在練習,所以我只打算每次上傳圖片都蓋掉id=1這筆資料
(在實際情況下,應該是每上傳一張圖就是新的一筆資料。)

上傳後的照片檔名會存在imgfile的欄位
而裁切過後的檔名會存在croped_photo的欄位
(我這裡的作法是,只要裁過照片,croped_photo這個值就會存在,且即便重新裁圖也是一樣,這個欄位的值不會變,只會去覆蓋這張圖)


各個檔案的說明:

  • link_db.php
    基本的資料庫連線,時區設定,編碼(utf-8)設定
  • upload.php
    要include('link_db.php');
    一個基本的form:
 <form method="post" action="upload.php" enctype="multipart/form-data">  
   <input type="hidden" value="204800" name="MAX_FILE_SIZE"/>  
   File: <input type="file" name="imgfile" />  
   <input type="submit" value="OK" name="submitbtn" style="width:100px;height:23px"/>  
  </form>  

POST出去後的動作在此頁處理,若file檢驗沒問題的話,update資料庫的某欄位(或新增一筆資料),將照片存在imgfile的欄位,然後轉頁到crop.php進行切圖。

  • crop.php
    要include('link_db.php');
    從資料庫撈出剛剛上傳的那一筆資料的imgfile的值
    匯入
    js/jquery.min.js
    js/jquery.Jcrop.js
    css/jquery.Jcrop.css
    在這頁寫crop的function(同官方網站即可)
    在這頁也會有個form,action會送到after_crop.php,method是POST,並且會將裁切的x,y座標與寬高(即$_POST['x'],  $_POST['y'], $_POST['w'], $_POST['h'])送到下一頁。
  • after_crop.php
    取得$_POST['x'],  $_POST['y'], $_POST['w'], $_POST['h']
    這裡會用到非常多跟php GD&圖片處理有關的函式....
    一時不知從何解釋起,暫時先放gist
  • https://gist.github.com/winwu/95b8be3a78ab889f4898
<?php include("link_db.php");?>
<!DOCTYPE HTML>
<html lang="en-US">
<head>
<meta charset="UTF-8">
<title>Crop Result</title>
<link rel="stylesheet" href="style.css" type="text/css" />
</head>
<body>
<?php
/**Please refer :
*http://www.php.net/manual/en/function.imagecreatefromjpeg.php
and http://php.net/manual/en/function.imagesx.php
http://www.5idev.com/p-php_gd.shtml
*/
echo"Request method is: <span style='color:red'>".$_SERVER['REQUEST_METHOD']."</span><br>";
echo "The POST Imformation:<br>";
print_r($_POST);
echo "裁切圖片的w點為:".$_POST['x']."<br>";
echo "裁切圖片的y點為:".$_POST['y']."<br>";
echo "裁切圖片的寬度為:".$_POST['w']."<br>";
echo "裁切圖片的高度為:".$_POST['h']."<br>";
echo "原圖檔名為:".$_POST['img_original_filename']."<br>";
$img_original_src = $_POST['img_original_src'];
//取得GIF、JPEG、PNG圖形的大小
$size = getimagesize($img_original_src);
#echo $size["mime"]; //得知該圖的mine type
//判斷user上傳的檔案類型是...
switch($size["mime"]){
case "image/jpeg":
$im = imagecreatefromjpeg($img_original_src) or die('Error ><');; //jpeg file
break;
case "image/gif":
$im = imagecreatefromgif($img_original_src) or die('Error ><');; //gif file
break;
case "image/png":
$im = imagecreatefrompng($img_original_src) or die('Error ><');; //png file
break;
default:
$im=false;
break;
}
$w = imagesx($im); //取得圖形的寬度
$h = imagesy($im); //取得圖形的高度
$im2 = ImageCreateTrueColor($_POST['w'], $_POST['h']);
//建立一個圖像寬度是新寬度 高度是新高度
imagecopyresampled($im2,$im,0,0,$_POST['x'],$_POST['y'],$_POST['w'],$_POST['h'],$_POST['w'],$_POST['h']);
$result_img = imagejpeg($im2,"after_save/".$_POST['img_original_filename']."_new.jpg",100);//另存新圖
//釋放記憶體空間
imagedestroy($im);
imagedestroy($im2);
?>
<img src="after_save/<?php echo $_POST['img_original_filename'];?>_new.jpg"/>
<?php
//save photo to database
$croped_photo = $_POST['img_original_filename']."_new.jpg";
$add_croped_image_sql = "UPDATE `images` SET `croped_photo` = '$croped_photo' WHERE `id`=1";
mysql_query($add_croped_image_sql)or die(mysql_error());
echo "儲存成功!";
?>
<a class="btn" href="javascript:void history.back();">Back,re-crop</a>
</body>
</html>
view raw after_crop.php hosted with ❤ by GitHub




實際操作的結果:
我沒有特別的去設計頁面><

這是upload.php頁面,選擇一個檔案之後 按下送出


上傳成功之後alert(alert是我拿來測試用的XD)
總之成功後會跳轉到crop.php


crop.php就是開始裁圖,按下裁切我吧,就會到下一頁after_crop.php


after_crop.php主要show一些debug用或是確定資料的訊息
然後確定裁切成功。

檢查upload跟after_save資料夾
upload資料夾存放原始檔案
after_save資料夾存放裁切後的圖片。


結語與心得:

第一次認真的接觸到PHP的GD以及圖片處理的函式,
雖然說挺複雜的,但是也帶來不少方便,
其實我原本是在想裁切圖片的功能可不可以都透過javascript來達成?!
答案是用node.js好像是可以的哦,
我已經看到好像網路上有人分享了node.js crop image的文章了,

另外用javacript寫crop的功能我看以我現在的能力我還不太可能達到
但也不一定要全部都靠一種framework
Jcrop也是一種方法
雖然我不會造輪子但是找輪子倒是挺ok的xd
方法有很多種,
我試過用jQuery UI的draggable來模擬切圖的功能,竟然也可以work
(因為draggable可以拖拉,跟裁切圖片的功能很像)
真是太有趣了:)



沒有留言:

張貼留言

若你看的文章,時間太久遠的問題就別問了,因為我應該也忘了... XD

Vue multiselect set autofocus and tinymce set autofocus

要在畫面一進來 focus multiselect 的方式: 參考: https://jsfiddle.net/shentao/mnphdt2g/ 主要就是在 multiselect 的 tag 加上 ref (例如: my_multiselect), 另外在 mounted...