最近由於項目需要,所以做了一個上傳頭像預覽並且可以預覽裁剪的功能,大概思路是上傳的圖片先保存到服務器,然后通過ajax從服務器獲取到圖片信息,再利用Jcrop插件進行裁剪,之后通過PHP獲取到的四個裁切點的坐標進行裁剪。
首先看一下uploadify上傳插件的API:
uploader : uploadify.swf 文件的相對路徑,該swf文件是一個帶有文字BROWSE的按鈕,點擊后淡出打開文件對話框,默認值:uploadify.swf。
script : 后台處理程序的相對路徑 。默認值:uploadify.php
checkScript :用來判斷上傳選擇的文件在服務器是否存在的后台處理程序的相對路徑
fileDataName :設置一個名字,在服務器處理程序中根據該名字來取上傳文件的數據。默認為Filedata
method : 提交方式Post 或Get 默認為Post
scriptAccess :flash腳本文件的訪問模式,如果在本地測試設置為always,默認值:sameDomain
folder : 上傳文件存放的目錄 。
queueID : 文件隊列的ID,該ID與存放文件隊列的div的ID一致。
queueSizeLimit : 當允許多文件生成時,設置選擇文件的個數,默認值:999 。
multi : 設置為true時可以上傳多個文件。
auto : 設置為true當選擇文件后就直接上傳了,為false需要點擊上傳按鈕才上傳 。
fileDesc : 這個屬性值必須設置fileExt屬性后才有效,用來設置選擇文件對話框中的提示文本,如設置fileDesc為“請選擇rar doc pdf文件”,打開文件選擇框效果如下圖:
fileExt : 設置可以選擇的文件的類型,格式如:’*.doc;*.pdf;*.rar’ 。
sizeLimit : 上傳文件的大小限制 。
simUploadLimit : 允許同時上傳的個數 默認值:1 。
buttonText : 瀏覽按鈕的文本,默認值:BROWSE 。
buttonImg : 瀏覽按鈕的圖片的路徑 。
hideButton : 設置為true則隱藏瀏覽按鈕的圖片 。
rollover : 值為true和false,設置為true時當鼠標移到瀏覽按鈕上時有反轉效果。
width : 設置瀏覽按鈕的寬度 ,默認值:110。
height : 設置瀏覽按鈕的高度 ,默認值:30。
wmode : 設置該項為transparent 可以使瀏覽按鈕的flash背景文件透明,並且flash文件會被置為頁面的最高層。 默認值:opaque 。
cancelImg :選擇文件到文件隊列中后的每一個文件上的關閉按鈕圖標,
onUploadSuccess : 上傳成功后執行的函數。
$("#fileUpload").uploadify({
'auto' : true, //選擇圖片后是否自動上傳
'multi' : false, //是否允許同時選擇多個(false一次只允許選中一張圖片)
'method' : 'post',
'swf' : 'images/uploadify.swf?v=' + ( parseInt(Math.random()*1000) ),
'uploader' : 'imgReceive.php', //上傳的接收者
'folder' : 'upload', //上傳圖片的存放地址
'fileObjName' : 'fileUpload',
'queueSizeLimit': 1, //最多能選擇加入的文件數量
'height' : '120px',
'width' : '120px',
'fileSizeLimit' : '2MB',
'progressData' : 'percentage',
'fileTypeExts' : '*.jpg; *.jpeg; *.png; *.bmp; *.gif;',
'overrideEvents': ['onSelectError','onDialogClose','onQueueComplete'],
'onSelectError' : function(file) {
alert('請將圖片的大小限制在2MB以下!');
},
'onUploadSuccess': function(file, data, response){
$("body").append('<div class="mask"></div>');
$("#previewWrapper").show();
var rst = JSON.parse(data);
if( rst.status == 0){
var $errorTip = $("<div id='errorMsg'>上傳失敗:"+ rst.info +"</div>");
$("#previewBox").append($errorTip);
}else{
var imageData = rst.data;
var imageUrl = imageData.path //圖片地址
var $image = $("<img />");
var previewBox = $("#previewBox");
previewBox.append( $image );
previewBox.children('img').attr('src', imageUrl +'?t='+ Math.random());
$("#img_url").val(imageUrl);
$image.attr('id', 'previewImg');
var $previewImg = $("#previewImg");
var img = new Image();
img.src = imageUrl +'?t='+ Math.random();
//根據圖片大小設置圖片居中
img.onload = function() {
var img_width = 0,
img_height = 0,
real_width = img.width,
real_height = img.height;
if (real_width > real_height && real_width > 400) {
var ratio = real_width / 400;
real_width = 400;
real_height = real_height / ratio;
}else if(real_height > real_width && real_height > 400) {
var ratio = real_height / 400;
real_height = 400;
real_width = real_width /ratio;
}
if(real_height < 400) {
img_height = (400 - real_height)/2;
}
if (real_width < 400) {
img_width = (400- real_width)/2;
}
previewBox.css({
width: (400 - img_width) + 'px',
height: (400 - img_height) + 'px',
paddingTop: (400 - real_height)/2
});
}
$("#previewImg").Jcrop({
bgFade : true,
aspectRatio : 1,
bgOpacity : .3,
minSize : [120, 120],
boxWidth : 400,
boxHeight : 400,
allowSelect: false, //是否可以選區,
allowResize: true, //是否可以調整選區大小
onChange : showPreview, //選框改變時的事件
onSelect: showPreview, //選框選定時的事件
setSelect : [0, 0, 400, 400]
});
}
}
});
另外取消uploadify上傳的一些默認設置需要設置css:
.uploadify{width: 120px; height: 120px;}
.uploadify-button{display: none;}
.swfupload{cursor: pointer;}
.uploadify-queue{display: none;}
同時再了解一下Jcrop插件的一些基本參數說明:
參考:http://code.ciaoca.com/jquery/jcrop/
調用Jcrop:
$("#previewImg").Jcrop({
bgFade : true,
aspectRatio : 1,
bgOpacity : .3,
minSize : [120, 120],
boxWidth : 400,
boxHeight : 400,
allowSelect: false, //是否可以選區,
allowResize: true, //是否可以調整選區大小
onChange : showPreview, //選框改變時的事件
onSelect: showPreview, //選框選定時的事件
setSelect : [0, 0, 400, 400]
});
bgColor : 背景顏色。顏色關鍵字、HEX、RGB 均可。
bgOpacity : 背景透明度
aspectRatio : 選框寬高比。說明:width/height
boxWidth : 畫布寬度
boxHeight : 畫布高度 (這里兩個參數一定要,不然獲取的圖片沒辦法進行CSS壓縮,至少我測試是這樣的)
minSelect:[0,0]:選框最小選擇尺寸。說明:若選框小於該尺寸,則自動取消選擇
maxSize:[0, 0] : 選框最大尺寸
minSize : [0, 0]: 選框最小尺寸
onChange : 選框改變時的事件
onSelect : 選框選定時的事件
setSelect(array):創建選框,參數格式為:[x, y, x2, y2]
------------------------------------------------------------------------------------------------------------------------------------------------------------
為了美觀一點,做了一個彈出層,當點擊上傳的時候彈出預覽框,html結構如下,
<link rel="stylesheet" href="css/style.css"> <link rel="stylesheet" type="text/css" href="css/jquery.Jcrop.css"> <script type="text/javascript" src="js/jquery-1.11.3.min.js"></script> <script type="text/javascript" src="js/jquery.uploadify.min.js"></script> <script type="text/javascript" src="js/jquery.jcrop.js"></script> <script type="text/javascript" src="js/myupload.js"></script>
<body>
<div class="main clearfix">
<div class="uploadBox">
<img src="images/default.jpg" id="avatar" alt="">
<input type="file" name="fileUpload" id="fileUpload" title="支持jpg、jpeg、gif、png格式,文件小於10M">
</div>
</div>
<div class="previewWrapper" id="previewWrapper">
<div id="previewBox"></div>
<form action="crop.php" method="post">
<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" id="img_url" name="src">
<p class="crop-tip">溫馨提示:請選擇要裁剪的區域</p>
<div class="previewBtn">
<a href="javascript:;" id="cancel">取消</a>
<a href="javascript:;" id="confirm">確定</a>
</div>
</form>
</div>
</body>
裁剪的JS代碼:
//提交裁剪好的圖片
var CutJson = {};
function showPreview(coords) {
var img_width = $("#previewImg").width();
var img_height = $("#previewImg").height();
var img_url = $("#img_url").val();
CutJson = {
'path': img_url,
'x': Math.floor(coords.x),
'y': Math.floor(coords.y),
'w': Math.floor(coords.w),
'h': Math.floor(coords.h)
};
console.log(CutJson);
}
//取消操作
$("#cancel").click(function() {
$("#previewBox").find('*').remove();
$("#previewWrapper").hide();
$(".mask").remove();
});
//確認裁剪
$("#confirm").click(function() {
$.ajax({
url: 'crop.php',
type: 'POST',
dataType: 'json',
data: {'crop': CutJson},
success: function(data, status, xhr) {
// console.log(data);
$("#avatar").attr("src",data.url);
$("#previewBox").find('*').remove();
$("#previewWrapper").hide();
$(".mask").remove();
}
});
})
接收上傳圖片的imgReceive.php文件和裁剪的crop.php文件如下:
imgReceive.php
<?php
header("Content-type: text/html; charset=utf-8");
$Handle = new UploadReceive();
$data = $Handle->receive($_FILES['fileUpload'],'/upload/');
echo json_encode($data);
class UploadReceive {
public function receive($file, $path) {
//存儲相對地址
$path = trim($path, '/').'/';
$savepath = rtrim(dirname(__FILE__),'/').'/'.$path;
//初始檢測
if($file['error'] > 0) {
$data['status'] = 0;
switch ($file['error']) {
case 1:
$data['info'] = '文件大小超過服務器限制';
break;
case 2:
$data['info'] = '文件太大!';
break;
case 3:
$data['info'] = '文件只加載了一部分!';
break;
case 4:
$data['info'] = '文件加載失敗!';
break;
}
return $data;
}
//大小檢測
if($file['size'] > 2*1024*1024){
$data['status'] = 0;
$data['info'] = '文件過大!';
return $data;
}
//類型檢測
$ext = pathinfo($file['name'], PATHINFO_EXTENSION);
$typeAllow = array('jpg','jpeg','gif','png');
if( in_array($ext, $typeAllow) ) {
$imginfo = getimagesize($file['tmp_name']);
if (empty($imginfo) || ($ext == 'gif' && empty($imginfo['bits']))) {
$data['status'] = 0;
$data['info'] = '非法圖像文件';
return $data;
}
}else{
$data['status'] = 0;
$data['info'] = '文件類型不符合!只接收'.implode(',',$typeAllow).'類型圖片';
return $data;
}
//存儲
$time = uniqid('upload_');
if (!is_dir($savepath)) {
if (!mkdir($savepath, 0777, true)) {
$data['status'] = 0;
$data['info'] = '上傳目錄不存在或不可寫!請嘗試手動創建:'.$savepath;
return $data;
}
}else {
if (!is_writable($savepath)) {
$data['status'] = 0;
$data['info'] = '上傳目錄不可寫!:'.$savepath;
return $data;
}
}
$filename = $time .'.'. $ext;
$upfile = $savepath . $filename;
if(is_uploaded_file($file['tmp_name'])){
if(!move_uploaded_file($file['tmp_name'], $upfile)){
$data['status'] = 0;
$data['info'] = '移動文件失敗!';
return $data;
}else{
$data['status'] = 1;
$data['info'] = '成功';
$arr = getimagesize( $upfile );
$strarr = explode("\"",$arr[3]);//分析圖片寬高
$data['data'] = array(
'path'=>$path.$filename,
'name'=>$filename,
'width'=>$strarr[1],
'height'=>$strarr[3]
);
return $data;
}
}else{
$data['status'] = 0;
$data['info'] = '文件丟失或不存在';
return $data;
}
}
}
?>
crop.php
<?php
header("Content-type: text/html; charset=utf-8");
$crop = $_POST['crop'];
if($crop) {
$targ_w = $targ_h = 120;
$src = $crop['path'];
$pathinfo = pathinfo($src);
$filename = 'upload/small_'.$pathinfo['basename'];
$img_r = imagecreatefromjpeg($src); //從url新建一圖像
$dst_r = imagecreatetruecolor($targ_w, $targ_h); //創建一個真色彩的圖片源
imagecopyresampled($dst_r, $img_r, 0, 0, $crop['x'], $crop['y'], $targ_w, $targ_h, $crop['w'], $crop['h']);
imagejpeg($dst_r, $filename, 90);
$data["url"]=$filename;
echo json_encode($data);
exit;
}
/**
* 裁剪不同圖像的類
*/
class cutImages
{
private $filename; //原文件全路徑
private $x; //橫坐標
private $y; //縱坐標
private $x1; //源圖寬
private $y1; //源圖高
private $ext; //文件后綴
private $width=120; //寬
private $height=120; //高
private $jpeg_quality=90; //圖片生成的保真度 范圍0(質量最差)-100(質量最好)
function __construct()
{
}
public function initialize($filename, $x, $y, $x1, $y1) {
if(file_exists($filename)) {
$this->filename = $filename;
$pathinfo = pathinfo($filename);
$this->ext = strtolower($pathinfo['extension']); //將擴展名轉換為小寫
}else {
$err = new Exception ('文件不存在!', 1050);
throw $err;
}
$this->x = $x;
$this->y = $y;
$this->x1 = $x1;
$this->y1 = $y1;
}
/**
* 生成截圖
* 根據不同的圖片格式生成不同的截圖
*/
public function generateShot() {
switch ($this->ext) {
case 'jpg':
$this-> generateJpg();
break;
case 'png':
$this-> generatePng();
break;
case 'gif':
$this-> generateGif();
break;
default:
return false;
}
}
/**
* 獲取生成的小圖文件
*
*/
public function getShotName() {
$pathinfo = pathinfo($this->filename);
$fileinfo = explode('.', $pathinfo['basename']);
$cutfilename = $fileinfo[0].'_small'.$this->ext;
return $pathinfo['dirname'].'/'.$cutfilename;
}
/**
*生成jpg格式圖片
*/
public function generateJpg() {
$shotname = $this->getShotName();
$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, $shotname, $this->jpeg_quality);
return $shotname;
}
/**
*生成png格式圖片
*/
public function generatePng() {
$shotname = $this->getShotName();
$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, $shotname, $this->jpeg_quality);
return $shotname;
}
/**
*生成gif格式圖片
*/
public function generateGif() {
$shotname = $this->getShotName();
$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, $shotname, $this->jpeg_quality);
return $shotname;
}
}
?>
最終效果如圖:

轉載:
http://www.cnblogs.com/yuanbiao/p/5007287.html

