用到几个插件:
1.Jquery上传插件: Fine Uploader
2.JS图片裁剪:imgAreaSelect
3.PHP上传/PHP GD库
原理:
PHP的imagecopy()函数可以将一张图片的一部分复制到另一张图片中,而imgAreaSelect可以获得用户裁剪图片的坐标及高宽,利用imgAreaSelect将需裁剪的x轴起点、y轴起点、宽、高四个参数传给PHP,PHP完成复制图片工作。
要点:
1.图片预览/截图。如果浏览器兼容FileApi ,问题就简单多,直接读取本地文件完成预览、获得截图的坐标和宽高等参数。考虑到IE10之前都不支持的情况,可以利用AJAX上传的方法,先将图片传到服务器,然后读取出来进行预览和裁剪。
2.PHP处理图片。PHP进行图片复制需要获得以下几个参数:原图片路径、x轴起点、y轴起点、宽、高。如果服务器支持ImageMagick扩展,可以直接利用Imagick::cropImage函数进行裁剪。不支持的话,可以采用最原始的方法,先用imagecreatetruecolor函数生成一副和截图区域等宽等高的空白图片,再用imagecopy将原图的截图复制过来。
关键代码:
1.PHP的处理
class Pic{
public $picInfo;
public function get_pic_info( $file ){
if( ($im = getimagesize($file)) == false ){
$this->error = "$file is not a valid image file";
return false;
}
$fileInfo = pathinfo( $file );
$info = array(
'width' => $im[0],
'height'=> $im[1],
'name' => $fileInfo['filename'],
'type' => strtolower($fileInfo['extension']),
'mime' => $im['mime'],
'path' => $fileInfo['dirname'].'/'
);
$this->picInfo = $info;
//return $info;
}
/**
* 截取图片
*
* @param $source_file 源文件地址
* @param $x 截取x轴起点
* @param $y 截取y轴起点
* @param $width 截取宽度
* @param $height 截取高度
* @return bool | resource
* @since v1.0
* @create 2012-12-20
*/
public function cut( $source_file, $x, $y, $width, $height ){
$this->get_pic_info( $source_file );
$info = $this->picInfo;
if( !$info ){
$this->error = "failed to get $source_file";
return false;
}
// 判断截取是否有效
if( $x>=$info['width'] || $y>=$info['height'] || $width>$info['width'] || $height>$info['height'] || !$width || !$height ){
$this->error = "invalid crop params";
return false;
}
$type = $info['type'] == 'jpg' ? 'jpeg' : $info['type'];
// 根据源文件类型创建对象
$func = "imagecreatefrom".$type;
if( ($im = $func( $source_file )) == false ){
$this->error = "create gd resource failed";
return false;
}
// 创建一个目标文件
$dst = imagecreatetruecolor( $width, $height );
// 设定背景色为白色
$color = imagecolorallocatealpha($dst, 255, 255, 255, 0);
imagefill( $dst, 0, 0, $color );
// 复制源文件的指定区域
if( !imagecopy( $dst, $im, 0, 0, $x, $y, $width, $height ) ){
$this->error = "copy image fail";
return false;
}
// 根据文件类型保存对象
$func = "image".$type;
ob_start();
if( $type=='jpeg' ){
$func( $dst, NULL, 85);
}else{
$func( $dst, NULL );
}
$newIm = ob_get_clean();
if( !$newIm ){
$this->error = "create image fail";
return false;
}
imagedestroy( $dst );
return $newIm;
}
}
2. JS的处理:
var picEditor;
var imguploader = $(‘#fileuploadbtn’).fineUploader({
request: {
endpoint: ‘upload.php’,
},validation: {
allowedExtensions: [‘jpeg’, ‘jpg’, ‘png’, ‘gif’],
sizeLimit: 2097152
},
text: {
uploadButton: ‘点击上传’
},
dragAndDrop: {
extraDropzones:[$(‘#dropzone’)],
hideDropzones: true,
disableDefaultDropzone: false,
},
template: ‘
‘ +
‘
{uploadButtonText}
‘ +
‘
‘ +
‘
‘
}).on(‘complete’, function(event, id, filename, json){
// ajax上传返回json数据
if (json.status) {
//初始化js裁剪插件,设置参数请参看官网文档
picEditor = $(‘#topfileupload img’).imgAreaSelect({
handles: true,
aspectRatio: ‘{$aspectRatio}’,
instance: true,
imageHeight: json.height,
imageWidth: json.width,
classPrefix: ‘imgareaselect’,
onSelectEnd: function(img, sel){
change_preview(sel);
}
});
} else {
if( json.info ) alert(‘上传失败:’+json.info);
}
}).on(‘error’,function(id,fileName,error){
alert(‘只允许上传小于2M的图片’);
});
// 将裁剪参数传给PHP处理
$(‘#btnSubmit’).click(function(){
if( !picEditor ){
$.bigpu.alert(‘请先上传图片’);
return;
}
var s = picEditor.getSelection();
var f = $(‘#topfileupload img’).attr(‘src’);
$.ajax({
url: ‘crop.php’,
data: ‘file=’+f+’&x=’+s.x1+’&y=’+s.y1+’&width=’+s.width+’&height=’+s.height,
dataType: ‘json’,
success: function(json){
if( json.status ){
picEditor.remove();
// PHP完成任务,返回Json供Js回调
pic_editor_success( json );
}else{
alert(‘图片保存失败%>_<%。');
}
}
});
})
// 截图预览
function change_preview(selection){
//预览宽高
var prevWidth = 100;
var prevHeight = 100;
if ( selection.width == 0 || selection.height == 0 || !prevWidth || !prevHeight ) { return false;}
// 缩放比例
var scaleX = prevWidth / selection.width;
var scaleY = prevHeight / selection.height;
// 预览定位
$('#imgPreview').css({
width: Math.round(scaleX * picInfo['oldWidth']) + 'px',
height: Math.round(scaleY * picInfo['oldHeight']) + 'px',
marginLeft: '-' + Math.round(scaleX * selection.x1) + 'px',
marginTop: '-' + Math.round(scaleY * selection.y1) + 'px'
});
// 记录位置
$('#x').val( selection.x1 );
$('#y').val( selection.y1 );
$('#w').val( selection.width );
$('#h').val( selection.height );
return;
}
[/javascript]