上传头像自定义裁切, JCROP 选区,AJAX 上传,PHP GD库裁切

AJAX 上传图片后,使用JCrop 插件作为前端选区工具,实时预览效果用户上传的头像图片尺寸过大时,程序会自动缩放到合理范围,防止页面撑破

没有使用常见的 flash 方式,可以放心在 苹果的 Mac Safari 上使用。

最终效果


程序分析:

前端:

<script type="text/javascript" language="javascript">
	var g_oJCrop = null;

	$(function(){
		new qq.FileUploader({
			element: document.getElementById('upload_avatar'),action: "controller.PHP?task=ajax_upload_avatar",multiple: false,disableDefaultDropzone: true,allowedExtensions: ["jpg","jpeg","png","gif"],uploadButtonText: '选择头像图片',onComplete: function(id,fileName,json) {
				if(json.success)
				{
					if(g_oJCrop!=null) g_oJCrop.destroy();
					
					$("#crop_tmp_avatar").val(json.tmp_avatar);
					$("#crop_container").show();
					$("#crop_target,#crop_preview").html('<img src="tmp/'+json.tmp_avatar+'">');

					$('#crop_target img').Jcrop({
						allowSelect: false,onChange: updatePreview,onSelect: updatePreview,aspectRatio: 1,minSize:[90,90]
					},function(){
						g_oJCrop = this;
						
						var bounds = g_oJCrop.getBounds();
						var x1,y1,x2,y2;
						if(bounds[0]/bounds[1] > 90/90)
						{
							y1 = 0;
							y2 = bounds[1];

							x1 = (bounds[0] - 90 * bounds[1]/90)/2
							x2 = bounds[0]-x1;
						}
						else
						{
							x1 = 0;
							x2 = bounds[0];
							
							y1 = (bounds[1] - 90 * bounds[0]/90)/2
							y2 = bounds[1]-y1;
						}
						g_oJCrop.setSelect([x1,y2]);
					});
				}
				else
				{
					alert(json.description);
				}
			}
		});

	});


	function updatePreview(c)
	{
	    $('#crop_x1').val(c.x);
		$('#crop_y1').val(c.y);
		$('#crop_x2').val(c.x2);
		$('#crop_y2').val(c.y2);
		$('#crop_w').val(c.w);
		$('#crop_h').val(c.h);

		if (parseInt(c.w) > 0)
		{
			var bounds = g_oJCrop.getBounds();

			var rx = 90 / c.w;
			var ry = 90 / c.h;
			
			$('#crop_preview img').css({
				width: Math.round(rx * bounds[0]) + 'px',height: Math.round(ry * bounds[1]) + 'px',marginLeft: '-' + Math.round(rx * c.x) + 'px',marginTop: '-' + Math.round(ry * c.y) + 'px'
			});
		}
	};



	function saveCropAvatar()
	{
		if($("#crop_tmp_avatar").val()=="")
		{
			alert("您还没有上传头像");
			return false;
		}
		
		$.ajax({
			type: "POST",url: "controller.PHP?task=ajax_crop",data: $("#form_crop_avatar").serialize(),dataType: "json",success: function(json)
			{
				if(json.success)
				{
					$("#crop_tmp_avatar").val("");
					$("#crop_container").hide();
					
					$("#my_avatar").html('<img src="avatars/'+json.avatar+'">');
				}
				else
				{
					alert(json.description);
				}
			}
		});
	}
</script>

服务器端 PHP 程序佝用 GD 库进行裁切
function crop($x=0,$y=0,$width=null,$height=null)
{
	if(!$this->image ) return false;
	if($x > $this->width || $y > $this->height) return false;

	if(!$width) $width = $this->width;
	if(!$height) $height = $this->height;

	if( ($x+$width)>$this->width )
	{
		$width = $this->width - $x;
	}

	if( ($y+$height)>$this->height )
	{
		$height = $this->height - $y;
	}

	$new_image = imagecreatetruecolor( $width,$height );
	if( $this->type == 'image/gif' )
	{
		$color = imagecolortransparent($this->image);
		imagepalettecopy($this->image,$new_image);
		imagefill($new_image,$color);
		imagecolortransparent($new_image,$color);
		imagetruecolortopalette($new_image,true,255);
		imagecopyresized($new_image,$this->image,$x,$y,$width,$height,$height);
	}
	else if( $this->type == 'image/png' || $this->type == 'image/x-png')
	{
		imagealphablending( $new_image,false );
		imagesavealpha($new_image,true);
		$color = imagecolorallocatealpha($new_image,255,127);
		imagefilledrectangle( $new_image,$color);
		imagecopyresampled( $new_image,$height);
	}
	else
	{
		imagealphablending( $new_image,false );
		imagecopyresampled( $new_image,$height);
	}

	imagedestroy($this->image);

	$this->image = $new_image;
	$this->width = $width;
	$this->height = $height;
}

缩放
/*
* 更改图像大小
$fit: 适应大小方式
'force': 把图片强制变形成 $width X $height 大小
'scale': 按比例在安全框 $width X $height 内缩放图片,输出缩放后图像大小 不完全等于 $width X $height
'scale_fill': 按比例在安全框 $width X $height 内缩放图片,安全框内没有像素的地方填充色,使用此参数时可设置背景填充色 $bg_color = array(255,255)(红,绿,蓝,透明度) 透明度(0不透明-127完全透明))
其它: 智能模能 缩放图像并载取图像的中间部分 $width X $height 像素大小
$fit = 'force','scale','scale_fill' 时: 输出完整图像
$fit = 图像方位值 时,输出指定位置截取的部分图像 
字母与图像的对应关系如下:

north_west   north   north_east

west         center        east

south_west   south   south_east

*/
function resize_to($width = 100,$height = 100,$fit = 'center',$fill_color = array(255,127) )
{
	if(!$this->image ) return false;

	$src_x = 0;
	$src_y = 0;
	$dest_x = 0;
	$dest_y = 0;
	$src_w = $this->width;
	$src_h = $this->height;
	$dest_w = $new_width = $width;
	$dest_h = $new_height = $height;

	switch($fit)
	{
		case 'force': break;
		case 'scale':
			if($this->width*$height > $this->height*$width)
			{
				$dest_h = $new_height = intval($this->height*$width/$this->width);
			}
			else
			{
				$dest_w = $new_width = intval($this->width*$height/$this->height);
			}
			break;
		case 'scale_fill':
			if($this->width*$height > $this->height*$width)
			{
				$dest_h = intval($this->height*$width/$this->width);
				$dest_y = intval( ($height-$dest_h)/2 );
			}
			else
			{
				$dest_w = intval($this->width*$height/$this->height);
				$dest_x = intval( ($width-$dest_w)/2 );
			}
			break;
		default:
		    
			if($this->width*$height > $this->height*$width)
			{
				$src_w = $width*$this->height/$height;
			}
			else
			{
				$src_h = $height*$this->width/$width;
			}
			
		switch($fit)
	    {
			case 'north_west':
			    $src_x = 0;
			    $src_y = 0;
			    break;
			case 'north':
			    $src_x = intval( ($this->width-$src_w)/2 );
			    $src_y = 0;
			    break;
			case 'north_east':
			    $src_x = $this->width-$src_w;
			    $src_y = 0;
			    break;
			case 'west':
			    $src_x = 0;
			    $src_y = intval( ($this->height-$src_h)/2 );
			    break;
			case 'center':
			    $src_x = intval( ($this->width-$src_w)/2 );
			    $src_y = intval( ($this->height-$src_h)/2 );
			    break;
			case 'east':
			    $src_x = $this->width-$src_w;
			    $src_y = intval( ($this->height-$src_h)/2 );
			    break;
			case 'south_west':
			    $src_x = 0;
			    $src_y = $this->height-$src_h;
			    break;
			case 'south':
			    $src_x = intval( ($this->width-$src_w)/2 );
			    $src_y = $this->height-$src_h;
			    break;
			case 'south_east':
			    $src_x = $this->width-$src_w;
			    $src_y = $this->height-$src_h;
			    break;
			default:
			    $src_x = intval( ($this->width-$src_w)/2 );
			    $src_y = intval( ($this->height-$src_h)/2 );
	    }
			
			break;
	}

	$new_image = imagecreatetruecolor( $new_width,$new_height );

	if( $this->type == 'image/gif' )
	{
		imagepalettecopy($this->image,$new_image);
		if($fill_color[3])
		{
			$color = imagecolorallocatealpha($new_image,$fill_color[0],$fill_color[1],$fill_color[2],$fill_color[3]);
			imagefill($new_image,$color);
			imagecolortransparent($new_image,$color);
		}
		else
		{
			$color = imagecolorallocate( $new_image,$fill_color[2] );
			imagefill($new_image,$color);
		}
		imagetruecolortopalette($new_image,$dest_x,$dest_y,$src_x,$src_y,$dest_w,$dest_h,$src_w,$src_h);
	}
	else if( $this->type == 'image/png' || $this->type == 'image/x-png')
	{
		imagealphablending( $new_image,$fill_color[3]);
		imagefilledrectangle( $new_image,$new_width,$new_height,$src_h);
	}
	else
	{
		imagealphablending( $new_image,false );
		if($fit=='scale_fill')
		{
			$color = imagecolorallocate( $new_image,$color);
		}
		imagecopyresampled( $new_image,$src_h);
	}

	imagedestroy($this->image);

	$this->image = $new_image;
	$this->width = $new_width;
	$this->height = $new_height;
}


下载地址:http://www.1024i.com/product/6.html

示例:http://www.1024i.com/product/demo/avator_crop/v1.0/

JCrop 官方网站:http://deepliquid.com/content/Jcrop.html

相关文章

IE6是一个非常老旧的网页浏览器,虽然现在很少人再使用它,但...
PHP中的count()函数是用来计算数组或容器中元素的个数。这个...
使用 AJAX(Asynchronous JavaScript and XML)技术可以在不...
Ajax(Asynchronous JavaScript and XML)是一种用于改进网页...
本文将介绍如何通过AJAX下载Excel文件流。通过AJAX,我们可以...
Ajax是一种用于客户端和服务器之间的异步通信技术。通过Ajax...