JS裁切头像并上传心得

基本原理:JS裁切头像,生成头像预览图,并获取图像坐标,相对缩放的宽高! 然后通过表单提交,将图片上传,并提交原点坐标,以及缩放后的相对宽高,然后在服务端再次裁切,通过服务器脚本语言的图像处理库,如php的gd库!!

php图像裁切函数代码:

private function uploadImageFile() { // Note: GD library is required for this function

	if ($_SERVER['REQUEST_METHOD'] == 'POST') {
		$iWidth = $iHeight = 200; // desired image result dimensions
		$iJpgQuality = 90;
		
		//$ext = end(explode('.',$_FILES['image_file']['name']));
		if ($_FILES) {
			// if no errors and size less than 250kb
			if (! $_FILES['image_file']['error']) {
				if (is_uploaded_file($_FILES['image_file']['tmp_name'])) {
				
				// new unique filename
				$sTempFileName = $_SERVER['DOCUMENT_ROOT'].'/upload/avatar/' . md5(time().rand());
				
				// move uploaded file into cache folder
				move_uploaded_file($_FILES['image_file']['tmp_name'],$sTempFileName);
				
				// change file permission to 644
				@chmod($sTempFileName, 0644);
				
				if (file_exists($sTempFileName) && filesize($sTempFileName) > 0) {
					$aSize = getimagesize($sTempFileName); // try to obtain image info
					if (!$aSize) {
						@unlink($sTempFileName);
						return;
					}
					
					// check for image type
					switch($aSize[2]) {
					case IMAGETYPE_JPEG:
					$sExt = '.jpg';
					
					// create a new image from file
					$vImg = @imagecreatefromjpeg($sTempFileName);
					break;
					case IMAGETYPE_PNG:
					$sExt = '.png';
					
					// create a new image from file
					$vImg = @imagecreatefrompng($sTempFileName);
					break;
					default:
					@unlink($sTempFileName);
					return;
				}
				
				
				// create a new true color image
				$vDstImg = @imagecreatetruecolor( $iWidth, $iHeight );
				
				// copy and resize part of an image with resampling
				imagecopyresampled($vDstImg, $vImg, 0, 0, (int)$_POST['dx'],(int)$_POST['dy'], $iWidth, $iHeight, (int)$_POST['dw'], (int)$_POST['dh']);
				
				// define a result image filename
				$sResultFileName = $sTempFileName . $sExt;
				
				// output image to file
				imagejpeg($vDstImg, $sResultFileName, $iJpgQuality);
				@unlink($sTempFileName);
				$returnurl = '/upload/avatar/'.end(explode('/',$sResultFileName));
				return $returnurl;
				}
				}
			}
		}
	}
}

js插件可以使用cropbox或者是jcrop;


自己修改过针对兼容性的cropbox.js

/**
 * Created by ezgoing on 14/9/2014.
 */

"use strict";
(function (factory) {
    if (typeof define === 'function' && define.amd) {
        define(['jquery'], factory);
    } else {
        factory(jQuery);
    }
}(function ($) {
    var cropbox = function(options, el){
        var el = el || $(options.imageBox),
            obj =
            {
                state : {},
                ratio : 1,
                options : options,
                imageBox : el,
                thumbBox : el.find(options.thumbBox),
                spinner : el.find(options.spinner),
                image : new Image(),
                getDataURL: function ()
                {
                    var width = this.thumbBox.width(),
                        height = this.thumbBox.height(),
                        canvas = document.createElement("canvas"),
                        dim = el.css('background-position').split(' '),
                        size = el.css('background-size').split(' '),
                        dx = parseInt(dim[0]) - el.width()/2 + width/2,
                        dy = parseInt(dim[1]) - el.height()/2 + height/2,
                        dw = parseInt(size[0]),
                        dh = parseInt(size[1]),
                        sh = parseInt(this.image.height),
                        sw = parseInt(this.image.width);
                    canvas.width  = width;
                    canvas.height = height;
                    var context = canvas.getContext("2d");
                    context.drawImage(this.image, 0, 0, sw, sh, dx, dy, dw, dh);
                    var imageData = canvas.toDataURL('image/png');
                    return imageData;
                },
                getPos: function(){
                    var width = this.thumbBox.width(),
                    height = this.thumbBox.height(),
                    canvas = document.createElement("canvas"),
                    dim  = el.css('background-position').split(' '),
                    size = el.css('background-size').split(' '),
                    dx = el.width()/2 - width/2-parseInt(dim[0]),
                    dy = el.height()/2 - height/2-parseInt(dim[1]),
                    dw = parseInt(size[0]),
                    dh = parseInt(size[1]),
                    sh = parseInt(this.image.height),
                    sw = parseInt(this.image.width);
                	obj.dx = dx;
                	obj.dy = dy;
                	obj.dw = width/obj.ratio;
                	obj.dh = height/obj.ratio;
                    return obj; 
                },
                getBlob: function()
                {
                    var imageData = this.getDataURL();
                    var b64 = imageData.replace('data:image/png;base64,','');
                    var binary = atob(b64);
                    var array = [];
                    for (var i = 0; i < binary.length; i++) {
                        array.push(binary.charCodeAt(i));
                    }
                    return  new Blob([new Uint8Array(array)], {type: 'image/png'});
                },
                zoomIn: function ()
                {
                    this.ratio*=1.1;
                    setBackground();
                },
                zoomOut: function ()
                {
                    this.ratio*=0.9;
                    setBackground();
                }
            },
            setBackground = function()
            {
                var w =  parseInt(obj.image.width)*obj.ratio;
                var h =  parseInt(obj.image.height)*obj.ratio;

                var pw = (el.width() - w) / 2;
                var ph = (el.height() - h) / 2;

                el.css({
                    'background-image': 'url(' + obj.image.src + ')',
                    'background-size': w +'px ' + h + 'px',
                    'background-position': pw + 'px ' + ph + 'px',
                    'background-repeat': 'no-repeat'});
            },
            imgMouseDown = function(e)
            {
                e.stopImmediatePropagation();

                obj.state.dragable = true;
                obj.state.mouseX = e.clientX;
                obj.state.mouseY = e.clientY;
            },
            imgMouseMove = function(e)
            {
                e.stopImmediatePropagation();

                if (obj.state.dragable)
                {
                    var x = e.clientX - obj.state.mouseX;
                    var y = e.clientY - obj.state.mouseY;

                    var bg = el.css('background-position').split(' ');

                    var bgX = x + parseInt(bg[0]);
                    var bgY = y + parseInt(bg[1]);

                    el.css('background-position', bgX +'px ' + bgY + 'px');

                    obj.state.mouseX = e.clientX;
                    obj.state.mouseY = e.clientY;
                }
            },
            imgMouseUp = function(e)
            {
                e.stopImmediatePropagation();
                obj.state.dragable = false;
            },
            zoomImage = function(e)
            {
                e.originalEvent.wheelDelta > 0 || e.originalEvent.detail < 0 ? obj.ratio*=1.1 : obj.ratio*=0.9;
                setBackground();
            }

        obj.spinner.show();
        obj.image.onload = function() {
            obj.spinner.hide();
            setBackground();

            el.bind('mousedown', imgMouseDown);
            el.bind('mousemove', imgMouseMove);
            $(window).bind('mouseup', imgMouseUp);
            el.bind('mousewheel DOMMouseScroll', zoomImage);
        };
        obj.image.src = options.imgSrc;
        el.bind('remove', function(){$(window).unbind('mouseup', imgMouseUp)});

        return obj;
    };

    jQuery.fn.cropbox = function(options){
        return new cropbox(options, this);
    };
}));



评论
添加红包

请填写红包祝福语或标题

红包个数最小为10个

红包金额最低5元

当前余额3.43前往充值 >
需支付:10.00
成就一亿技术人!
领取后你会自动成为博主和红包主的粉丝 规则
hope_wisdom
发出的红包
实付
使用余额支付
点击重新获取
扫码支付
钱包余额 0

抵扣说明:

1.余额是钱包充值的虚拟货币,按照1:1的比例进行支付金额的抵扣。
2.余额无法直接购买下载,可以购买VIP、付费专栏及课程。

余额充值