就我而言,頁面上的設計比較靈動的部分,其實不是很多,諸如滑動驗證碼,圖片裁剪等比較好的交互設計。
從剛開始工作的時候,我就想把這些東西了解下,無奈一直沒這個需求,乘着今天的空閑,研究了一下午,期間遇到了大大小小的問題,一直備受折磨,這其實也反映一個問題,我的
還是比較薄弱。
話不多說,先大概講下效果:
用戶點擊上傳圖片后,頁面顯示所上傳的圖片,並且出現裁剪框和兩個預覽區域,最后點擊裁剪按鈕保存裁剪的圖片到服務器上。
效果很簡單,整個過程我遇到的兩個難點,第一個是裁剪的JS效果,第二個則是圖片數據的處理。
對於第一個問題,我引用了網上的一個插件,就我感覺來說,裁剪過程用戶的滿意度只能算一般,因為它只能裁剪正方形區域,就算邊框上有八個拉動設置,但是拉動框時還是按正方
形縮放,就這點不太讓我滿意。
以下是簡單的頁面設計:
<div style="float:left;"><img id="target"></div>
<div style="width:48px;height:48px;margin:10px;overflow:hidden; float:left;"><img style="float:left;" id="preview" ></div>
<div style="width:190px;height:195px;margin:10px;overflow:hidden; float:left;"><img style="float:left;" id="preview2" ></div>
<form action="{:U('/test/crop_deal')}" method="post" onsubmit="return checkCoords()" enctype="multipart/form-data" id="form">
<input type="file" name="file" onchange="change_image(this)">
<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="submit" value="裁剪"/>
</form>
下面是JS代碼:
function change_image(file){
var reader = new FileReader();
reader.onload = function(evt){
$("#target").attr('src',evt.target.result);
$('#preview').attr('src',evt.target.result);
$('#preview2').attr('src',evt.target.result);
// $('#target').css({"height":"600px","width":"600px"});
// 限制了大小會影響到截圖的效果
};
reader.readAsDataURL(file.files[0]);
var jcrop_api, boundx, boundy;
setTimeout(function(){
$('#target').Jcrop({
minSize: [48,48],
setSelect: [0,0,190,190],
onChange: updatePreview,
onSelect: updatePreview,
onSelect: updateCoords,
aspectRatio: 1
},
function(){
// Use the API to get the real image size
var bounds = this.getBounds();
boundx = bounds[0];
boundy = bounds[1];
// Store the API in the jcrop_api variable
jcrop_api = this;
});
function updatePreview(c){
if (parseInt(c.w) > 0)
{
var rx = 48 / c.w; //小頭像預覽Div的大小
var ry = 48 / c.h;
$('#preview').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'
});
}
{
var rx = 199 / c.w; //大頭像預覽Div的大小
var ry = 199 / c.h;
$('#preview2').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'
});
}
};
function updateCoords(c)
{
$('#x').val(c.x);
$('#y').val(c.y);
$('#w').val(c.w);
$('#h').val(c.h);
};
},500);
}
這里稍作兩點提醒:
其一:不要忘記在頁面頭部引入插件:
<script src="/plug/js/jquery.min.js" type="text/javascript"></script>
<script src="/plug/js/jquery.Jcrop.min.js" type="text/javascript"></script>
<link rel="stylesheet" href="/plug/css/Jcrop.css" type="text/css" />
其二:有些人眼尖的話可能看到了JS里有個定時,同時心理是不是很疑惑這不是有點多此一舉嗎?其實不是,上傳圖片到JS加載到頁面上,是需要時間的,這個定時的意義在於
等到圖片被JS加載到頁面上時才去加載裁剪效果,這里也是反復實驗后得出的做法。
后端PHP處理我用的是THINKPHP框架,版本是3.1.3
貼上代碼:
function crop_deal(){
ob_clean();
import ( 'ORG.Net.UploadFile' );
$upload = new UploadFile ();
$upload->maxSize = 2000000;
$upload->allowExts = array (
'jpg',
'gif',
'png',
'jpeg'
);
$upload->savePath = './upload/test/';
$upload->autoSub = true;
$upload->subType = 'date';
$upload->dateFormat = 'Ymd';
if ($upload->upload () ) {
$info = $upload->getUploadFileInfo();
$new_path = "./upload/test/thumb".date('Ymd');
$file_store = $new_path."/".date('YmdHis').".jpg";
if(!file_exists($new_path)){
mkdir($new_path,0777,true);
}
$source_path = "http://".$_SERVER['HTTP_HOST']."/upload/test/".$info[0]['savename'];
$img_size = getimagesize($source_path);
$width = $img_size[0];
$height = $img_size[1];
$mime = $img_size['mime'];
$srcImg = imagecreatefromstring(file_get_contents($source_path));
$cropped_img = imagecreatetruecolor($_POST['w'], $_POST['h']);
//縮放
// imagecopyresampled($cropped_img,$srcImg,0,0,$_POST['x'],$_POST['y'],$_POST['w'],$_POST['h'],$width,$height);
//裁剪
imagecopy($cropped_img,$srcImg,0,0,$_POST['x'],$_POST['y'],$_POST['w'],$_POST['h']);
header("Content-Type:image/jpeg");
imagejpeg($cropped_img,$file_store);
imagedestroy($srcImg);
imagedestroy($cropped_img);
}
}
這里就是調用GD庫里創建圖像的一系列方法,最重要就是imagecopy(),它是將原圖按規定的裁剪位置,裁剪大小復制到新的圖片上去,這也說明了一件事,頁面用戶在裁剪圖片
的時候其實前端並沒有對圖片操作,而是得到裁剪時的坐標位置,裁剪大小,然后提交到PHP操作!!
以上就是忙了半天的成果,好了,下班!!