头像上传和裁剪(uploadify+Jcrop+php)
2014-03-18 10:42
751 查看
最近项目里面需要用到上传和裁剪头像的功能,一开始采用的是美图秀秀,这是一款功能非常强大的插件,而且集成起来非常简单和方便,但是因为一个美女同事电脑跟该款软件不协调以及领导认为它的功能过于强大,所以该方案就被cut掉了,在网上查找了N多资料后,花费一天时间终于用uploadify
+ Jcrop + php 完整实现该功能,,特此mark一下!
这套方案的思路是先用uploadify将图片上传到服务器上面,然后前台得到Ajax中图片的路径显示到前台,然后通过jcrop进行裁剪并将裁剪后的参数传递到后台通过php裁剪干刚刚上传的图片,并删除以前上传的图片。
Uploadify
Uploadify是JQuery的一个上传插件,实现的效果非常不错,带进度显示,用起来也非常简单,我用的是当前最新版本ver3.2.1, 用过的同学应该知道它和以前的版本有一些区别,它添加了一个swf的参数用来设置上传按钮的样式,该样式可以通过修改uploadify.css文件来进行修改,所以如果程序中出现图片资源找不到的情况可以在里面进行修改。
支持单文件或多文件上传,可控制并发上传的文件数
在服务器端支持各种语言与之配合使用,诸如PHP,.NET,Java……
通过参数可配置上传文件类型及大小限制
通过参数可配置是否选择文件后自动上传
易于扩展,可控制每一步骤的回调函数(onSelect, onCancel……)
通过接口参数和CSS控制外观
html代码:
<div class="avatarEditor" >
<input type="file" name="file" class="uploadify" id="uploadify"/>
<a class="hide-info btn btn-primary js-avatar-edit avatar__setting-submit">确认编辑</a>
<img src="" class="js-file-jcrop">
</div>
js程序代码如下:
$('#uploadify').uploadify({
auto: true,
swf: themePath + '/css/resource/uploadify.swf',
uploader: 'saveAvatar',
buttonText: '图片上传',
fileObjName: 'userAvatarUrl',
fileSizeLimit: '2048KB',
onUploadSuccess: _handleUploadResponse,
});
function _handleUploadResponse(file, data, response) {
var imageUrl = JSON.parse(data).url;
$('.js-avatar-container img').attr('src', imageUrl);
cropImage.url = imageUrl;
$('.js-file-jcrop').Jcrop({
allowResize: false,
aspectRatio: 1,
setSelect: [0, 0, 110, 110],
onSelect: _setImageParams
});
$('.js-avatar-edit').show();
}
function _setImageParams(coords) {
cropImage.height = coords.h;
cropImage.width = coords.w;
cropImage.x = coords.x;
cropImage.y = coords.y;
}
function _sendCropParams() {
//用Ajax把cropImage传送的后台并处理response
}
这是初始化Uploadify插件,有一点要注意,一定要用id选择器,因为在它的源代码中:
id : $this.attr('id'), // The ID of the DOM object
swf : 'uploadify.swf', // The path to the uploadify SWF file
uploader : 'uploadify.php', // The path to the server-side upload script
大家可以看到也是运用了id当作选择的核心元素来使用的,如果不是id的话会报一个类似于 null element的错误!
uploadify参数:
auto
buttonClass
buttonCursor
buttonImage
buttonText
checkExisting
debug
fileObjName
fileSizeLimit
fileTypeDesc
fileTypeExts
formData
height
itemTemplate
method
multi
overrideEvents
preventCaching
progressData
queueID
queueSizeLimit
removeCompleted
removeTimeout
requeueErrors
successTimeout
swf
uploader
uploadLimit
width
jcrop参数:
api方法
php 代码:
public function actionSaveAvatar()
{
$response = array();
if (!$this->_user->isGuest)
{
$uploadFile = $_FILES['userAvatarUrl'];
$result = $this->_moveAvatar($uploadFile, $this->_user->id);
if ($result['response'])
{
$response['status'] = STATUS_SUCCESS;
$response['url'] = $this->_getUserAvatar($result['url']);
}
else
{
$response['status'] = STATUS_FAIL;
}
}
else
{
$response['status'] = 'timeout';
}
$this->responseJSON($response);
}
private function _moveAvatar($file, $userId)
{
$imageFormat = array('image/gif', 'image/jpeg', 'image/pjpeg');
$result = array();
// if (in_array($file['type'], $imageFormat)
// && ($file['size'] < 2048000)
// && ($file['error'] === 0))
if ($file['size'] < 2048000)
{
$fileType = $this->_getUploadfileType($file['name']);
$newName = 'upload/' .md5($userId) .'_tmp' . $fileType;
$moveResult = move_uploaded_file($file['tmp_name'], $newName);
if ($moveResult)
{
$result['response'] = true;
$result['url'] = $newName;
}
else
{
$result['response'] = false;
}
}
else
{
$result['response'] = false;
}
return $result;
}
private function _getUploadfileType($fileName)
{
$num = strrpos($fileName, '.');
$len = strlen($fileName);
return substr($fileName, $num, $len - 1);
}
private function _genarateImageUrl($fileUrl)
{
$basePath = dirname(Yii::app()->BasePath) . 'upload/';
$num = strrpos($fileUrl, '/upload');
return substr($fileUrl, $num, strlen($fileUrl) - 1);
}
public function actionSaveCropAvatar()
{
if (!$this->_user->isGuest && $this->_request->isPostRequest)
{
$cropImage = $this->_request->getPost('data');
$imageBasePath = dirname(Yii::app()->BasePath) . $this->_genarateImageUrl($cropImage['url']);
$newImageUrl = str_ireplace('_tmp.', '.', $imageBasePath);
$thisimage = imagecreatetruecolor($cropImage['width'], $cropImage['height']);
$oldimg = imagecreatefromjpeg($imageBasePath);
imagecopy($thisimage, $oldimg, 0, 0, $cropImage['x'], $cropImage['y'], $cropImage['width'], $cropImage['height']);
$result = imagejpeg($thisimage, $newImageUrl, 100);//完成剪切后将裁剪后的图片复制到指定目录中
$response = array();
if ($result)
{
$userId = $this->_user->id;
$user = User::model()->findByPk($userId);
$user->picture = str_ireplace('_tmp.', '.', $cropImage['url']);
$this->saveData($user);
$response['status'] = STATUS_SUCCESS;
}
else
{
$response['status'] = STATUS_FAIL;
}
$this->responseJSON($response);
}
}
+ Jcrop + php 完整实现该功能,,特此mark一下!
这套方案的思路是先用uploadify将图片上传到服务器上面,然后前台得到Ajax中图片的路径显示到前台,然后通过jcrop进行裁剪并将裁剪后的参数传递到后台通过php裁剪干刚刚上传的图片,并删除以前上传的图片。
Uploadify
Uploadify是JQuery的一个上传插件,实现的效果非常不错,带进度显示,用起来也非常简单,我用的是当前最新版本ver3.2.1, 用过的同学应该知道它和以前的版本有一些区别,它添加了一个swf的参数用来设置上传按钮的样式,该样式可以通过修改uploadify.css文件来进行修改,所以如果程序中出现图片资源找不到的情况可以在里面进行修改。
支持单文件或多文件上传,可控制并发上传的文件数
在服务器端支持各种语言与之配合使用,诸如PHP,.NET,Java……
通过参数可配置上传文件类型及大小限制
通过参数可配置是否选择文件后自动上传
易于扩展,可控制每一步骤的回调函数(onSelect, onCancel……)
通过接口参数和CSS控制外观
html代码:
<div class="avatarEditor" >
<input type="file" name="file" class="uploadify" id="uploadify"/>
<a class="hide-info btn btn-primary js-avatar-edit avatar__setting-submit">确认编辑</a>
<img src="" class="js-file-jcrop">
</div>
js程序代码如下:
$('#uploadify').uploadify({
auto: true,
swf: themePath + '/css/resource/uploadify.swf',
uploader: 'saveAvatar',
buttonText: '图片上传',
fileObjName: 'userAvatarUrl',
fileSizeLimit: '2048KB',
onUploadSuccess: _handleUploadResponse,
});
function _handleUploadResponse(file, data, response) {
var imageUrl = JSON.parse(data).url;
$('.js-avatar-container img').attr('src', imageUrl);
cropImage.url = imageUrl;
$('.js-file-jcrop').Jcrop({
allowResize: false,
aspectRatio: 1,
setSelect: [0, 0, 110, 110],
onSelect: _setImageParams
});
$('.js-avatar-edit').show();
}
function _setImageParams(coords) {
cropImage.height = coords.h;
cropImage.width = coords.w;
cropImage.x = coords.x;
cropImage.y = coords.y;
}
function _sendCropParams() {
//用Ajax把cropImage传送的后台并处理response
}
这是初始化Uploadify插件,有一点要注意,一定要用id选择器,因为在它的源代码中:
id : $this.attr('id'), // The ID of the DOM object
swf : 'uploadify.swf', // The path to the uploadify SWF file
uploader : 'uploadify.php', // The path to the server-side upload script
大家可以看到也是运用了id当作选择的核心元素来使用的,如果不是id的话会报一个类似于 null element的错误!
uploadify参数:
auto
buttonClass
buttonCursor
buttonImage
buttonText
checkExisting
debug
fileObjName
fileSizeLimit
fileTypeDesc
fileTypeExts
formData
height
itemTemplate
method
multi
overrideEvents
preventCaching
progressData
queueID
queueSizeLimit
removeCompleted
removeTimeout
requeueErrors
successTimeout
swf
uploader
uploadLimit
width
jcrop参数:
allowSelect | true | 允许新选框 |
allowMove | true | 允许选框移动 |
allowResize | true | 允许选框缩放 |
trackDocument | true | |
baseClass | "jcrop" | 基础样式名前缀。说明:class="jcrop-holder",更改的只是其中的 jcrop。 |
addClass | null | 添加样式会。例:假设值为 "test",那么会添加样式到 class="test jcrop-holder" |
bgColor | "black" | 背景颜色。颜色关键字、HEX、RGB 均可。 |
bgOpacity | 0.6 | 背景透明度 |
bgFade | false | 使用背景过渡效果 |
borderOpacity | 0.4 | 选框边框透明度 |
handleOpacity | 0.5 | 缩放按钮透明度 |
handleSize | 9 | 缩放按钮大小 |
handleOffset | 5 | 缩放按钮与边框的距离 |
aspectRatio | 0 | 选框宽高比。说明:width/height |
keySupport | true | 支持键盘控制。按键列表:上下左右(移动)、Esc(取消)、Tab(跳出裁剪框,到下一个) |
cornerHandles | true | 允许边角缩放 |
sideHandles | true | 允许四边缩放 |
drawBorders | true | 绘制边框 |
dragEdges | true | 允许拖动边框 |
fixedSupport | true | |
touchSupport | null | |
boxWidth | 0 | 画布宽度 |
boxHeight | 0 | 画布高度 |
boundary | 2 | 边界。说明:可以从边界开始拖动鼠标选择裁剪区域 |
fadeTime | 400 | 过度效果的时间 |
animationDelay | 20 | 动画延迟 |
swingSpeed | 3 | 过渡速度 |
minSelect | [0,0] | 选框最小选择尺寸。说明:若选框小于该尺寸,则自动取消选择 |
maxSize | [0,0] | 选框最大尺寸 |
minSize | [0,0] | 选框最小尺寸 |
onChange | function(){} | 选框改变时的事件 |
onSelect | function(){} | 选框选定时的事件 |
onRelease | function(){} | 取消选框时的事件 |
名称 | 说明 |
---|---|
setImage(string) | 设定(或改变)图像。例:jcrop_api.setImage("newpic.jpg") |
setOptions(object) | 设定(或改变)参数,格式与初始化设置参数一样 |
setSelect(array) | 创建选框,参数格式为:[x,y,x2,y2] |
animateTo(array) | 用动画效果创建选框,参数格式为:[x,y,x2,y2] |
release() | 取消选框 |
disable() | 禁用 Jcrop。说明:已有选框不会被清除。 |
enable() | 启用 Jcrop |
destroy() | 移除 Jcrop |
tellSelect() | 获取选框的值(实际尺寸)。例子:console.log(jcrop_api.tellSelect()) |
tellScaled() | 获取选框的值(界面尺寸)。例子:console.log(jcrop_api.tellScaled()) |
getBounds() | 获取图片实际尺寸,格式为:[w,h] |
getWidgetSize() | 获取图片显示尺寸,格式为:[w,h] |
getScaleFactor() | 获取图片缩放的比例,格式为:[w,h] |
public function actionSaveAvatar()
{
$response = array();
if (!$this->_user->isGuest)
{
$uploadFile = $_FILES['userAvatarUrl'];
$result = $this->_moveAvatar($uploadFile, $this->_user->id);
if ($result['response'])
{
$response['status'] = STATUS_SUCCESS;
$response['url'] = $this->_getUserAvatar($result['url']);
}
else
{
$response['status'] = STATUS_FAIL;
}
}
else
{
$response['status'] = 'timeout';
}
$this->responseJSON($response);
}
private function _moveAvatar($file, $userId)
{
$imageFormat = array('image/gif', 'image/jpeg', 'image/pjpeg');
$result = array();
// if (in_array($file['type'], $imageFormat)
// && ($file['size'] < 2048000)
// && ($file['error'] === 0))
if ($file['size'] < 2048000)
{
$fileType = $this->_getUploadfileType($file['name']);
$newName = 'upload/' .md5($userId) .'_tmp' . $fileType;
$moveResult = move_uploaded_file($file['tmp_name'], $newName);
if ($moveResult)
{
$result['response'] = true;
$result['url'] = $newName;
}
else
{
$result['response'] = false;
}
}
else
{
$result['response'] = false;
}
return $result;
}
private function _getUploadfileType($fileName)
{
$num = strrpos($fileName, '.');
$len = strlen($fileName);
return substr($fileName, $num, $len - 1);
}
private function _genarateImageUrl($fileUrl)
{
$basePath = dirname(Yii::app()->BasePath) . 'upload/';
$num = strrpos($fileUrl, '/upload');
return substr($fileUrl, $num, strlen($fileUrl) - 1);
}
public function actionSaveCropAvatar()
{
if (!$this->_user->isGuest && $this->_request->isPostRequest)
{
$cropImage = $this->_request->getPost('data');
$imageBasePath = dirname(Yii::app()->BasePath) . $this->_genarateImageUrl($cropImage['url']);
$newImageUrl = str_ireplace('_tmp.', '.', $imageBasePath);
$thisimage = imagecreatetruecolor($cropImage['width'], $cropImage['height']);
$oldimg = imagecreatefromjpeg($imageBasePath);
imagecopy($thisimage, $oldimg, 0, 0, $cropImage['x'], $cropImage['y'], $cropImage['width'], $cropImage['height']);
$result = imagejpeg($thisimage, $newImageUrl, 100);//完成剪切后将裁剪后的图片复制到指定目录中
$response = array();
if ($result)
{
$userId = $this->_user->id;
$user = User::model()->findByPk($userId);
$user->picture = str_ireplace('_tmp.', '.', $cropImage['url']);
$this->saveData($user);
$response['status'] = STATUS_SUCCESS;
}
else
{
$response['status'] = STATUS_FAIL;
}
$this->responseJSON($response);
}
}
相关文章推荐
- 一个关于if else容易迷惑的问题
- PHP5.2.*防止Hash冲突拒绝服务攻击的Patch
- 深入理解PHP之匿名函数
- JSP/PHP基于Ajax的分页功能实现
- 分享一款flash头像编辑上传利器:富头像上传编辑器
- 富头像上传编辑器 v1.5
- 关于PHP通过PDO用中文条件查询MySQL的问题。
- 什么是设计模式
- PHP数据库长连接mysql_pconnect的细节
- Php Installing An Expansion
- PHP+Apache在Windows 9x下的安装和配置
- IIS 6 的 PHP 最佳配置方法
- 安装Apache和PHP的一些补充
- Linux Apache+MySQL+PHP
- 建立Apache+PHP+MySQL数据库驱动的动态网站
- PHP 5.3.0 安装分析心得
- apache 环境下 php 的配置注意事项
- ASP.NET、ASP、PHP、JSP之间有什么区别?
- PHP VBS JS 函数 对照表