我前端用JCROP擷取到x、y座標、寬度、高度,傳遞到 uphoto.php處理,現在一切正常,但是如果前端使用者選擇的圖片寬度過大(我用css樣式控制使用者選擇的圖片最大寬度為680px),裁切出來的就不正常了...我查閱了一些資料,說是需要按比例換算,但是是按什麼比例換算啊,使用者選擇的圖片的寬度(大於680px時)和680換算嗎?
這是 uphoto.php:
$x1 = $_POST["x1"];$x2 = $_POST["x2"];$y1 = $_POST["y1"];$y2 = $_POST["y2"];$targ_w = $_POST["w"];$targ_h = $_POST["h"];if ($_FILES["mfile"]["error"]){echo "error: " . $_FILES["file"]["error"];}if (!empty($_FILES["mfile"]["name"])){ //提取檔案域內容名稱,並判斷$path = "/upload/user/photo/"; //上傳路徑//檢查是否有該檔案夾,如果沒有就建立,並給予最高許可權//if(!file_exists($path)){mkdir("$path", 0700);}//允許上傳的檔案格式$allow_type = array("image/gif","image/pjpeg","image/jpeg","image/png");//檢查上傳檔案是否在允許上傳的類型if(!in_array($_FILES["mfile"]["type"], $allow_type)){echo "error:格式有誤,僅支援gif/jpg/png"; exit();}//檢測圖片大小if($_FILES["mfile"]["size"] > 5*1024*1024){echo "error:檔案不得超過5M"; exit();}$filetype = $_FILES["mfile"]["type"];if($filetype == "image/jpeg"){$img_type = ".jpg";}if ($filetype == "image/jpg") {$img_type = ".jpg";}if ($filetype == "image/pjpeg") {$img_type = ".jpg";}if($filetype == "image/gif"){$img_type = ".gif";}if($filetype == "image/png"){$img_type = ".png";}if($_FILES["mfile"]["name"]){$randstr = random_str().date("YmdHis"); //擷取時間並賦值給變數$saveto = $_SERVER['DOCUMENT_ROOT'].$path.$randstr.$img_type; //圖片的完整路徑$newimg = $randstr.$img_type; //圖片名稱$flag=1;}//END IFif ($flag){$result = move_uploaded_file($_FILES["mfile"]["tmp_name"], $saveto);}//特別注意這裡傳遞給move_uploaded_file的第一個參數為上傳到伺服器上的臨時檔案$src_file = $saveto;}}$type = exif_imagetype($src_file);$support_type = array(IMAGETYPE_JPEG , IMAGETYPE_PNG , IMAGETYPE_GIF);if(!in_array($type, $support_type, true)){echo "error:當前圖片格式非JPG/PNG/GIF";exit();}//Load imageswitch($type) {case IMAGETYPE_JPEG :$src_img = imagecreatefromjpeg($src_file);break;case IMAGETYPE_PNG :$src_img = imagecreatefrompng($src_file);break;case IMAGETYPE_GIF :$src_img = imagecreatefromgif($src_file);break;default:echo "Load image error!";exit();}$dst_r = ImageCreateTrueColor($targ_w, $targ_h);list($width_orig, $height_orig) = getimagesize($src_file);//if ($width_orig > 680){//$new_width_orig = 680;//$new_height_orig = ($height_orig*680)/$width_orig;//}//else {//$new_width_orig = $targ_w;//$new_height_orig = $targ_h;//}//echo $new_width_orig."
";//echo $new_height_orig."
";//echo "x:".$x1."
";//echo "y:".$y1;//exit();imagecopyresampled($dst_r, $src_img, 0, 0, $x1, $y1, $targ_w, $targ_h, $targ_w, $targ_h);//imagecopyresampled($dst_r, $src_img, 0, 0, $x1, $y1, $targ_w, $targ_h, $targ_w, $targ_h);switch($type) {case IMAGETYPE_JPEG :header('Content-type: image/jpeg');imagejpeg($dst_r, null, 100);break;case IMAGETYPE_PNG :header('Content-type: image/png');imagepng($dst_r, null, 100);break;case IMAGETYPE_GIF :header('Content-type: image/gif');imagegif($dst_r, null, 100);break;default:break;}echo "";exit;
求大神指點指點
回複討論(解決方案)
用css樣式控制使用者選擇的圖片最大寬度為680px
就表示使用者看到的是經過動態縮放的副本
那麼你在傳遞裁剪地區座標的時候,還需傳遞圖片的原始大小
換算一下就可以了
X= x/680*圖片寬
用css樣式控制使用者選擇的圖片最大寬度為680px
就表示使用者看到的是經過動態縮放的副本
那麼你在傳遞裁剪地區座標的時候,還需傳遞圖片的原始大小
換算一下就可以了
X= x/680*圖片寬
謝謝啊,按你那樣換算了 還是不正常..
list($width_orig, $height_orig) = getimagesize($src_file);
if ($width_orig > 680){
$nx = $x1/680 * $width_orig;
}
else {
$nx = $x1;
}
imagecopyresampled($dst_r, $src_img, 0, 0, $nx, $y1, $targ_w, $targ_h, $targ_w, $targ_h);
你 y 方向沒有計算
list($width_orig, $height_orig) = getimagesize($src_file);
if ($width_orig > 680){
$nx = $x1/680 * $width_orig;
$new_height = $height_orig*680/$width_orig;
$ny = $y1/$new_height * $height_orig;
}
else {
$nx = $x1;
$ny = $y1;
}
imagecopyresampled($dst_r, $src_img, 0, 0, $nx, $ny, $targ_w, $targ_h, $targ_w, $targ_h);
這樣計算麼,也還是不行..
$targ_w, $targ_h 這兩個是裁切的寬度和高度 會不會跟這兩個有關呢?
可以參考一下我之前寫的裁剪。因為你是要裁剪,所以寬和高有一個是和裁剪後的尺寸的寬和高一樣,另一邊會>=裁剪後的。
http://blog.csdn.net/fdipzone/article/details/9316385
/** 擷取靶心圖表產生的size * @return Array $width, $height */ private function get_size(){ list($owidth, $oheight) = getimagesize($this->_source); $width = (int)($this->_width); $height = (int)($this->_height); switch($this->_type){ case 'fit': $pic_w = $width; $pic_h = (int)($pic_w*$oheight/$owidth); if($pic_h>$height){ $pic_h = $height; $pic_w = (int)($pic_h*$owidth/$oheight); } break; case 'crop': $pic_w = $width; $pic_h = (int)($pic_w*$oheight/$owidth); if($pic_h<$height){ $pic_h = $height; $pic_w = (int)($pic_h*$owidth/$oheight); } break; } return array($pic_w, $pic_h); }
可以參考一下我之前寫的裁剪。因為你是要裁剪,所以寬和高有一個是和裁剪後的尺寸的寬和高一樣,另一邊會>=裁剪後的。
http://blog.csdn.net/fdipzone/article/details/9316385
/** 擷取靶心圖表產生的size * @return Array $width, $height */ private function get_size(){ list($owidth, $oheight) = getimagesize($this->_source); $width = (int)($this->_width); $height = (int)($this->_height); switch($this->_type){ case 'fit': $pic_w = $width; $pic_h = (int)($pic_w*$oheight/$owidth); if($pic_h>$height){ $pic_h = $height; $pic_w = (int)($pic_h*$owidth/$oheight); } break; case 'crop': $pic_w = $width; $pic_h = (int)($pic_w*$oheight/$owidth); if($pic_h<$height){ $pic_h = $height; $pic_w = (int)($pic_h*$owidth/$oheight); } break; } return array($pic_w, $pic_h); }
謝謝啊 , 按你那樣調整了,還是不正常的額:
list($width_orig, $height_orig) = getimagesize($src_file);
$pic_w = $targ_w;
$pic_h = (int)($pic_w*$height_orig/$width_orig);
if($pic_h < $targ_h){
$pic_h = $targ_h;
$pic_w = (int)($pic_h*$width_orig/$height_orig);
}
imagecopyresampled($dst_r, $src_img, 0, 0, $x1, $y1, $targ_w, $targ_h, $pic_w, $pic_h);
我現在是想把寬度680的圖片裁切成寬度680px,然後在裁切...
寬度大於680的圖片裁切成寬度680px
由 圖片寬 / 圖片高 = 680 / h
得 h = 680 / 圖片寬 * 圖片高
即
$targ_h = 680 / $pic_w * $pic_h;
$targ_w = 680;
寬度大於680的圖片裁切成寬度680px
由 圖片寬 / 圖片高 = 680 / h
得 h = 680 / 圖片寬 * 圖片高
即
$targ_h = 680 / $pic_w * $pic_h;
$targ_w = 680;
謝謝啊,我現在通過將使用者選擇的圖片若超過680px就裁切成寬度680px(高度通過你那樣的演算法算的),然後再裁切成頭像,測試是正常的,但還有幾個細節我有點不明白,下面是源碼:
$x1 = $_POST["x1"];$x2 = $_POST["x2"];$y1 = $_POST["y1"];$y2 = $_POST["y2"];$targ_w = $_POST["w"];$targ_h = $_POST["h"];if ($_FILES["mfile"]["error"]){echo "error: " . $_FILES["file"]["error"];}if (!empty($_FILES["mfile"]["name"])){ //提取檔案域內容名稱,並判斷$path = "/upload/user/photo/"; //上傳路徑//檢查是否有該檔案夾,如果沒有就建立,並給予最高許可權//if(!file_exists($path)){mkdir("$path", 0700);}//允許上傳的檔案格式$allow_type = array("image/gif","image/pjpeg","image/jpeg","image/png");//檢查上傳檔案是否在允許上傳的類型if(!in_array($_FILES["mfile"]["type"], $allow_type)){echo "error:格式有誤,僅支援gif/jpg/png"; exit();}//檢測圖片大小if($_FILES["mfile"]["size"] > 5*1024*1024){echo "error:檔案不得超過5M"; exit();}$filetype = $_FILES["mfile"]["type"];if($filetype == "image/jpeg"){$img_type = ".jpg";}if ($filetype == "image/jpg") {$img_type = ".jpg";}if ($filetype == "image/pjpeg") {$img_type = ".jpg";}if($filetype == "image/gif"){$img_type = ".gif";}if($filetype == "image/png"){$img_type = ".png";}if($_FILES["mfile"]["name"]){$randstr = random_str().date("YmdHis"); //擷取時間並賦值給變數$saveto = $_SERVER['DOCUMENT_ROOT'].$path.$randstr.$img_type; //圖片的完整路徑$newimg = $randstr.$img_type; //圖片名稱$flag=1;}//END IFif ($flag){$result = move_uploaded_file($_FILES["mfile"]["tmp_name"], $saveto);}//特別注意這裡傳遞給move_uploaded_file的第一個參數為上傳到伺服器上的臨時檔案$src_file = $saveto;}}list($width_orig, $height_orig) = getimagesize($src_file);if ($width_orig > 680){$tmp_type = exif_imagetype($src_file);switch($tmp_type) {case IMAGETYPE_JPEG :$tmp_src_img = imagecreatefromjpeg($src_file);break;case IMAGETYPE_PNG :$tmp_src_img = imagecreatefrompng($src_file);break;case IMAGETYPE_GIF :$tmp_src_img = imagecreatefromgif($src_file);break;default:echo "Load image error!";exit();}$ntmp_width = 680;$ntmp_height = $height_orig*$ntmp_width/$width_orig;$ntmp_imgr = ImageCreateTrueColor($ntmp_width, $ntmp_height);imagecopyresampled($ntmp_imgr, $tmp_src_img, 0, 0, 0, 0, $ntmp_width, $ntmp_height, $width_orig, $height_orig);switch($tmp_type) {case IMAGETYPE_JPEG :header('Content-type: image/jpeg');imagejpeg($ntmp_imgr, $_SERVER['DOCUMENT_ROOT'].$path.$randstr.$img_type, 100);break;case IMAGETYPE_PNG :header('Content-type: image/png');imagepng($ntmp_imgr, $_SERVER['DOCUMENT_ROOT'].$path.$randstr.$img_type, 100);break;case IMAGETYPE_GIF :header('Content-type: image/gif');imagegif($ntmp_imgr, $_SERVER['DOCUMENT_ROOT'].$path.$randstr.$img_type, 100);break;default:break;}$src_file = $_SERVER['DOCUMENT_ROOT'].$path.$randstr.$img_type;}$type = exif_imagetype($src_file);switch($type) {case IMAGETYPE_JPEG :$src_img = imagecreatefromjpeg($src_file);break;case IMAGETYPE_PNG :$src_img = imagecreatefrompng($src_file);break;case IMAGETYPE_GIF :$src_img = imagecreatefromgif($src_file);break;default:echo "Load image error!";exit();}$dst_r = ImageCreateTrueColor($targ_w, $targ_h);imagecopyresampled($dst_r, $src_img, 0, 0, $x1, $y1, $targ_w, $targ_h, $targ_w, $targ_h);switch($type) {case IMAGETYPE_JPEG :header('Content-type: image/jpeg');imagejpeg($dst_r, null, 100);break;case IMAGETYPE_PNG :header('Content-type: image/png');imagepng($dst_r, null, 100);break;case IMAGETYPE_GIF :header('Content-type: image/gif');imagegif($dst_r, null, 100);break;default:break;}echo "";exit;
其中那個紅色部分,我如果換成上傳的圖片的寬度和高度($width_orig,$height_orig),就會不正常...
按我現在這樣的方式,有沒辦法最佳化下?
我看好多使用裁切之後 都會 imagedestory() 這個是刪除圖片流,而不是原圖吧?
圖片的寬、高 應通過 imagesx($src_img)、imagesy($src_img) 取得,傳入的可能不正確
imagedestory() 是釋放資源,比如 imagedestory($src_img)
不寫也可以,php 會替你釋放的
圖片的寬、高 應通過 imagesx($src_img)、imagesy($src_img) 取得,傳入的可能不正確
imagedestory() 是釋放資源,比如 imagedestory($src_img)
不寫也可以,php 會替你釋放的
謝謝啊 我現在想把裁切好的圖片儲存到資料庫中,卻出現 映像 ... 因存在錯誤而無法顯示。
這是代碼:
$dst_r = ImageCreateTrueColor($targ_w, $targ_h);
imagecopyresampled($dst_r, $src_img, 0, 0, $x1, $y1, $targ_w, $targ_h, $targ_w, $targ_h);
$mphoto = $path.$uid.$randstr.$img_type;
$mphoto_save = $_SERVER['DOCUMENT_ROOT'].$mphoto;
//echo $mphoto_save;
//exit();
switch($type) {
case IMAGETYPE_JPEG :
header('Content-type: image/jpeg');
imagejpeg($dst_r, $mphoto_save, 100);
break;
case IMAGETYPE_PNG :
header('Content-type: image/png');
imagepng($dst_r, $mphoto_save, 100);
break;
case IMAGETYPE_GIF :
header('Content-type: image/gif');
imagegif($dst_r, $mphoto_save, 100);
break;
default:
break;
}
//echo "";
//exit();
imagedestory($dst_r);
imagedestory($src_img);
if (!mysqli_query($conn, "update dh_member set photo='". $mphoto ."' where id=". $uid ."")){die(mysqli_error($conn));}
echo "";
exit();
是怎麼回事啊,我都沒有輸出圖片啊..
假定 $dst_r 是 image 資源
imagegif($dst_r); 就是輸出圖片資料流
imagegif($dst_r, '圖片檔案名稱'); 就是儲存到檔案
資料庫儲存圖片檔案名稱即可
如果資料庫要儲存圖片資料,則應用合適的 blob 類型欄位
資料從 圖片檔案 讀取或攔截php的輸出
用 bin2hex 函數轉換成字串,在前面加 ‘0x'
假定 $dst_r 是 image 資源
imagegif($dst_r); 就是輸出圖片資料流
imagegif($dst_r, '圖片檔案名稱'); 就是儲存到檔案
資料庫儲存圖片檔案名稱即可
如果資料庫要儲存圖片資料,則應用合適的 blob 類型欄位
資料從 圖片檔案 讀取或攔截php的輸出
用 bin2hex 函數轉換成字串,在前面加 ‘0x'
謝謝啊,怎麼做到讓它不輸出圖片流呢(輸出圖片流為的就是儲存成新檔案名稱),直接儲存到檔案夾,然後更新資料庫呢?