jfinal头像裁剪上传服务器

前端页面完整代码,复制可用,记得导入库文件

<!DOCTYPE html>
<html lang="en">
<head>
<title>Aspect Ratio with Preview Pane | Jcrop Demo</title>
<meta http-equiv="Content-type" content="text/html;charset=UTF-8" />

<script src="/Jcrop-0.9.12/js/jquery.min.js"></script>
<script src="/Jcrop-0.9.12/js/jquery.Jcrop.js"></script>
<script src="/Jcrop-0.9.12/js/imgCropUpload.js"></script>

<link rel="stylesheet" href="/Jcrop-0.9.12/css/jquery.Jcrop.css"
    type="text/css" />
<style type="text/css">
body {
    font-size: 16px;
    font-family: "Microsoft YaHei", Arial, Helvetica, sans-serif
}

*, *:before, *:after {
    -webkit-box-sizing: border-box;
    -moz-box-sizing: border-box;
    -ms-box-sizing: border-box;
    box-sizing: border-box;
}

.crop-picker-wrap {
    position: relative;
    width: 100px;
    height: 30px;
    overflow: hidden;
}

.crop-picker {
    width: 100%;
    height: 100%;
    line-height: 1;
    -webkit-appearance: none;
    margin: 0;
    border: none;
    border-radius: 5px;
    padding: 9px 0;
    background-color: #1ab2ff;
    color: #fff;
    cursor: pointer;
}

.crop-picker-file {
    position: absolute;
    top: 0;
    right: 0;
    height: 100%;
    opacity: 0;
    cursor: pointer;
    filter: alpha(opacity = 0);
}

.crop-wrapper {
    display: inline-block;
    min-width: 750px;
    margin: 10px 0;
    padding: 10px;
    border: 1px solid #ccc;
    border-radius: 5px;
    box-shadow: 0 0 5px 2px #ccc;
}

.crop-container {
    font-size: 0;
}

.crop-container img[src=""] {
    visibility: hidden;
}

.crop-area-wrapper, .crop-preview-wrapper {
    display: inline-block;
    vertical-align: top;
}

.crop-area-wrapper {
    width: 500px;
    height: 400px;
}

.crop-preview-wrapper {
    width: 200px;
    height: 200px;
    margin-left: 28px;
    overflow: hidden;
}

.crop-preview-container {
    position: relative;
    overflow: hidden;
}

.crop-operate {
    text-align: center;
    margin: 10px 0;
}

.crop-save, .crop-cancel {
    display: inline-block;
    vertical-align: middle;
    width: 150px;
    height: 50px;
    line-height: 50px;
    -webkit-appearance: none;
    margin: 0 5px;
    border: none;
    border-radius: 5px;
    background-color: #1ab2ff;
    color: #fff;
    cursor: pointer;
}

#uploadIfr {
    display: none;
}

.crop-picker-wrap {
    position: relative;
    width: 100px;
    height: 30px;
    overflow: hidden;
    margin-top: 10px;
}
</style>

</head>
<body>

    <form id="coords" class="coords" onsubmit="return false;" action="">

        <div class="inline-labels">
            <label>X1 <input type="text" size="4" id="x1" name="x1" /></label> <label>Y1
                <input type="text" size="4" id="y1" name="y1" />
            </label> <label>X2 <input type="text" size="4" id="x2" name="x2" /></label>
            <label>Y2 <input type="text" size="4" id="y2" name="y2" /></label> <label>W
                <input type="text" size="4" id="w" name="w" />
            </label> <label>H <input type="text" size="4" id="h" name="h" /></label>
        </div>
    </form>

    <div id="TCrop"></div>
    <button id="btn">上传头像</button>
    <script type="text/javascript">
            $(function() {
                Crop.init({
                    id: ‘TCrop‘,
                    /* 上传路径 */
                    url: ‘‘,
                    /* 允许上传的图片的后缀 */
                    allowsuf: [‘jpg‘, ‘jpeg‘, ‘png‘, ‘gif‘],
                    /* JCrop参数设置 */
                    cropParam: {
                        minSize: [100, 100],          // 选框最小尺寸
                        maxSize: [300, 300],        // 选框最大尺寸
                        allowSelect: true,          // 允许新选框
                        allowMove: true,            // 允许选框移动
                        allowResize: true,          // 允许选框缩放
                        dragEdges: true,            // 允许拖动边框
                        onChange: function(c) {
                            $(‘#x1‘).val(c.x);
                            $(‘#y1‘).val(c.y);
                            $(‘#x2‘).val(c.x2);
                            $(‘#y2‘).val(c.y2);
                            $(‘#w‘).val(c.w);
                            $(‘#h‘).val(c.h);
                        },   // 选框改变时的事件,参数c={x, y, x1, y1, w, h}
                        onSelect: function(c) {
                             $(‘#x1‘).val(c.x);
                            $(‘#y1‘).val(c.y);
                            $(‘#x2‘).val(c.x2);
                            $(‘#y2‘).val(c.y2);
                            $(‘#w‘).val(c.w);
                            $(‘#h‘).val(c.h);

                        }    // 选框选定时的事件,参数c={x, y, x1, y1, w, h}
                    },
                    /* 是否进行裁剪,不裁剪则按原图上传,默认进行裁剪 */
                    isCrop: true,
                    /* 图片上传完成之后的回调,无论是否成功上传 */
                    onComplete: function(data) {
                        console.log(‘upload complete!‘);
                    }
                });
            });

        /* 上传头像 */
        $(function(){
            $("#btn").click(function(){
            var form = document.getElementById("coords");//获取到form表单
                var formData = new FormData(form);//创建一个formData对象,将表单中的数据放进去
                //for(var i=0; i<$(‘#file‘)[0].files.length;i++){//使用for循环将选择的文件一个一个添加(append)到formData对象中
                    formData.append(‘img0‘, $(‘#file‘)[0].files[0]);//注意:如果你使用的是jfinal框架这里的key(img)必须是不同的,如果相同的话文件能上传但是拿上传文件名的时候只能拿到一个
                //}
                   var x1 = $(‘#x1‘).val(),
                    x2 = $(‘#x2‘).val(),
                    y1 = $(‘#y1‘).val(),
                    y2 = $(‘#y2‘).val();
                    formData.append(‘x11‘,x1 );
                    formData.append(‘y11‘,y1 );
                    formData.append(‘x22‘,x2 );
                    formData.append(‘y22‘,y2 );
                    formData.append(‘tw‘,$(".jcrop-holder").css("width") );
                    formData.append(‘ty‘,$(".jcrop-holder").css("height") );
                $.ajax({//ajax
                    url: "/upload/uploadHeaderPic",
                    type: "POST",
                    processData : false,//不处理数据,必须为false
                    contentType : false,//不设置内容类型,必须为false
                    data: formData,
                    dataType:"json",
                    success: function(data){
                            //layer.msg(data.msg)
                            alert(data.msg);
                           console.log("msg",data.msg)
                    },
                    error:function(e){
                            console.log("msg","ajax调用出现错误")
                    }

                });
             });
        });
    </script>
</body>
</html>
这个js文件网上找的,经过同事帮助改动。目前可用,有些地方看不懂,不过这个js,我主要用的地方就是图片的预览。参数传递还是自己写方法进行传的


;(function(global, $, Crop) {
    var defaultOpt = {
        /* 整个图片选择、裁剪、上传区域的最外围包裹元素id,默认TCrop */
        id: ‘TCrop‘,
        /* 上传路径 */
        url: ‘‘,
        /* 允许上传的图片的后缀,暂时支持以下四种,其余格式图片未测试 */
        allowsuf: [‘jpg‘, ‘jpeg‘, ‘png‘, ‘gif‘],
        /* JCrop参数设置 */
        cropParam: {
            minSize: [50, 50],          // 选框最小尺寸
            maxSize: [300, 300],        // 选框最大尺寸
            allowSelect: true,          // 允许新选框
            allowMove: true,            // 允许选框移动
            allowResize: true,          // 允许选框缩放
            dragEdges: true,            // 允许拖动边框
            onChange: function(c) {},   // 选框改变时的事件
            onSelect: function(c) {}    // 选框选定时的事件,参数c={x, y, x1, y1, w, h}
        },
        /* 是否进行裁剪,不裁剪则按原图上传,默认进行裁剪 */
        isCrop: true,
        /* 图片上传完成之后的回调,无论是否成功上传 */
        onComplete: function(data) {
            console.log(‘upload complete!‘);
        }
    };

    /* 记录jcrop实例 */
    var jcropApi;

    /* 创建Dom结构 */
    /* 完整DOM结构 --s-- */
    /*
    <iframe id="uploadIfr" name="uploadIfr" class="crop-upload-ifr"></iframe>
    <form action="index.html" enctype="multipart/form-data" method="post" target="uploadIfr">
        <input type="hidden" name="cropData">
        <div class="crop-picker-wrap">
            <button class="crop-picker" type="button">选择图片</button>
            <input type="file" id="file" class="crop-picker-file">
        </div>
        <div class="crop-wrapper">
            <div class="crop-container clearfix">
                <div class="crop-area-wrapper"><img src="" ></div>
                <div class="crop-preview-wrapper"><img src="" ></div>
            </div>
            <div class="crop-operate">
                <div class="crop-save">上传原图</div>
                <div class="crop-save">保存截图</div>
                <div class="crop-cancel">取消</div>
            </div>
        </div>
    </form>
    */
    /* 完整DOM结构 --e-- */
    function _createDom($wrap, opt) {
        var accept = ‘image/‘ + opt.allowsuf.join(‘, image/‘);
        var $ifr = $(‘<iframe id="uploadIfr" name="uploadIfr" class="crop-hidden"></iframe>‘);
        var $form = $(‘<form action="‘ + opt.url + ‘" enctype="multipart/form-data" method="post" target="uploadIfr"/>‘);
        var $cropDataInp = $(‘<input type="hidden" name="cropData">‘);
        var $picker = $(‘<div class="crop-picker-wrap"><button class="crop-picker" type="button">选择图片</button></div>‘);
        var $fileInp = $(‘<input type="file" id="file" accept="‘ + accept + ‘" class="crop-picker-file">‘);
        $picker.append($fileInp);
        $form.append($cropDataInp).append($picker);

        var $cropWrap = $(‘<div class="crop-wrapper crop-hidden"/>‘);
        var $cropArea = $(‘<div class="crop-area-wrapper"></div>‘);
        var $cropPreviewWrap = $(‘<div class="crop-preview-wrapper"></div>‘);
        var $cropPreview = $(‘<div class="crop-preview-container"/>‘);
        $cropPreviewWrap.append($cropPreview);
        var $cropContainer = $(‘<div class="crop-container"/>‘).append($cropArea).append($cropPreviewWrap);
        $cropWrap.append($cropContainer);
        // var $saveSource = $(‘<div class="crop-save">上传原图</div>‘);
        //var $save = $(‘<div class="crop-save">保存</div>‘);
       // var $cropCancel = $(‘<div class="crop-cancel">取消</div>‘);
       // var $cropOpe = $(‘<div class="crop-operate"/>‘).append($save).append($cropCancel);

        if(!opt.isCrop) {
            $cropPreviewWrap.addClass(‘crop-hidden‘);
        }

       // $cropWrap.append($cropOpe);
        $form.append($cropWrap);

        $wrap.append($ifr).append($form);

        return {
                $ifr: $ifr,
                $form: $form,
                $cropDataInp: $cropDataInp,
                $cropPicker: $picker,
                $fileInp: $fileInp,
                $cropWrap: $cropWrap,
                $cropArea: $cropArea,
                $cropPreview: $cropPreview,
                // $saveSource: $saveSource,
               // $save: $save,
                //$cancel: $cropCancel
            };
    };

    /*
     * 绑定事件
     *
     */
    function _bind($cropObj, opt) {

        var $cropPicker = $cropObj.$cropPicker;
        var $fileInp = $cropObj.$fileInp;
        var $save = $cropObj.$save;
        var $cancel = $cropObj.$cancel;
        var $ifr = $cropObj.$ifr;

        $fileInp.change(function(eve) {
            if(!this.value) {return ;}
            var fileSuf = this.value.substring(this.value.lastIndexOf(‘.‘) + 1);
            if(!_checkSuf(fileSuf, opt.allowsuf)) {
                alert(‘只允许上传后缀名为‘ + opt.allowsuf.join(‘,‘) + ‘的图片‘);
                return ;
            }
            /* 进入裁剪流程 */
            _crop($cropObj, this);
            $cropPicker.addClass(‘crop-hidden‘).next().removeClass(‘crop-hidden‘);
        });

      /*  $save.click(function(eve) {
            eve.preventDefault();
            Crop.upload();
        });*/

        /*$cancel.click(function(eve) {
            eve.preventDefault();
            Crop.cancel();
        });
*/
        /* iframe的load应该延迟绑定,避免首次插入文档中加载完毕时触发load事件 */
        window.setTimeout(function() {
            $ifr.load(function() {
                var body = this.contentWindow.document.body;
                var text = body.innerText;
                opt.onComplete(text);
            });
        }, 100);
    };

    /* 检查文件是否符合上传条件 */
    function _checkSuf(fileSuf, suffixs) {
        for(var i = 0, j = suffixs.length;i < j; i ++) {
            if(fileSuf.toLowerCase() == suffixs[i].toLowerCase()) {
                return true;
            }
        }
        return false;
    };

    /* 主要裁剪流程 */
    function _crop($cropObj, fileInp) {
        var cropArea = $cropObj.$cropArea.get(0);
        var cropPreview = $cropObj.$cropPreview.get(0);
        var opt = _getOpt();
        var jcropOpt = opt.cropParam;
        cropArea.innerHTML = ‘‘;
        if(fileInp.files && fileInp.files[0]) {
            var img = document.createElement(‘img‘);
            img.style.visibility = ‘hidden‘;
            cropArea.appendChild(img);

            img.onload = function() {
                /* 在图片加载完成之后便可以获取原图的大小,根据原图大小和预览区域大小获取图片的缩放比例以及原图在预览时所展现的大小 */
                var scaleOpt = _getScale(cropArea.clientWidth, cropArea.clientHeight, img.offsetWidth, img.offsetHeight);
                img.setAttribute(‘style‘, ‘position: absolute;visibility: visible;width: ‘ + scaleOpt.w + ‘px;height: ‘ + scaleOpt.h + ‘px‘);

                if(!opt.isCrop) {return ;}

                var cropPreviewImg = img.cloneNode(true);
                cropPreview.appendChild(cropPreviewImg);

                _startCrop(img, jcropOpt);

                /* 记录原始比例,上传数据需要还原实际裁剪尺寸 */
                Crop.ratio = scaleOpt.scale;
                /* 记录裁剪图片及裁剪预览图像对象,更新预览图时需要使用 */
                Crop.cropPreview = {
                    cropAreaImg: img,
                    cropPreviewImg: cropPreviewImg
                };
            };
            var fr = new FileReader();
            fr.onload = function(eve) {
                img.src = eve.target.result;
            }
            fr.readAsDataURL(fileInp.files[0]);
        } else {
            var img = document.createElement(‘div‘);
            img.style.visibility = ‘hidden‘;
            img.style.width = ‘100%‘;
            img.style.height = ‘100%‘;
            cropArea.appendChild(img);

            fileInp.select();
            var src = document.selection.createRange().text;
            // console.log(document.selection.createRange());

            var img_filter = "progid:DXImageTransform.Microsoft.AlphaImageLoader(sizingMethod=‘image‘,src=‘" + src + "‘)";
            img.style.filter = img_filter;

            /* 需等待滤镜加载完毕之后才能进行下一步操作 */
            window.setTimeout(function() {
                _loadFiter(cropArea, img);
            }, 100);
        }
    };

    /* 加载滤镜,等待两秒,超时则判定加载失败 */
    function _loadFiter(cropArea, img) {
        var time = 0;
        if(img.offsetWidth != cropArea.clientWidth) {
            /* 滤镜加载成功,进入裁剪流程 */
            _filterCrop(cropArea, img);
        } else {
            time ++;
            if(time < 20) {
                window.setTimeout(function() {
                    _loadFiter(cropArea, img);
                }, 100);
            } else {
                alert(‘图片加载失败,请重试!‘);
            }
        }
    };

    /* 使用滤镜的裁剪 */
    function _filterCrop(cropArea, img) {
        var scaleOpt = _getScale(cropArea.clientWidth, cropArea.clientHeight, img.offsetWidth, img.offsetHeight);
        /* 更改滤镜设置 */
        var s_filter = img.style.filter.replace(/sizingMethod=‘image‘/g, "sizingMethod=‘scale‘");
        var jcropOpt = _getOpt().cropParam;

        img.setAttribute(‘style‘, ‘position: absolute;visibility: visible;width: ‘ + scaleOpt.w + ‘px;height: ‘ + scaleOpt.h + ‘px;filter: ‘ + s_filter);

        if(!_getOpt().isCrop) {return ;}

        var cropPreview = cropArea.nextSibling.firstChild;
        var cropPreviewImg = img.cloneNode(true);
        cropPreview.appendChild(cropPreviewImg);

        _startCrop(img, jcropOpt);

        /* 记录原始比例,上传数据需要还原实际裁剪尺寸 */
        Crop.ratio = scaleOpt.scale;
        /* 记录裁剪图片及裁剪预览图像对象,更新预览图时需要使用 */
        Crop.cropPreview = {
            cropAreaImg: img,
            cropPreviewImg: cropPreviewImg
        };
    };

    /* 开始裁剪,初始化裁剪插件 */
    function _startCrop(img, jcropOpt) {
        var imgW = img.offsetWidth;
        var imgH = img.offsetHeight;
        var minW = jcropOpt.minSize[0], minH = jcropOpt.minSize[1];
        var offsetWidth = (imgW / 2) - (minW / 2);
        var offsetHeight = (imgH / 2) - (minH / 2);
        var obj = {
            x: offsetWidth,
            y: offsetHeight,
            x2: offsetWidth + minW,
            y2: offsetHeight + minH,
            w: minW,
            h: minH
        };
        $(img).Jcrop(jcropOpt, function() {
            jcropApi = this;
            this.animateTo([obj.x, obj.y, obj.x2, obj.y2]);
        });
    };

    /* 获取配置参数opt */
    function _getOpt() {
        var id = Crop.crop.id;
        var cropDom = document.getElementById(id);
        var opt = $.data(cropDom, ‘crop‘).opt;
        return opt;
    };

    /*
     * 获取缩放比例
     *
     * 原始宽高vw,vh
     * 实际显示宽高sw,sh
     * 返回:
     * {w,h,scale:max(sw/vw,sh/vh)}
     * w,h均为缩放到sw、sh后的宽高
     */
    function _getScale(vw, vh, sw, sh) {
        vw = Number(vw);
        vh = Number(vh);
        sw = Number(sw);
        sh = Number(sh);
        if(vw <= 0 || vh <= 0) {
            console.log(‘参数不能为0‘);
            return false;
        }
        var wScale = sw / vw;
        var hScale = sh / vh;
        var scale = 1, w, h;

        if(wScale > hScale) {
            scale = wScale;
            w = vw;
            h = sh / scale;
        } else {
            scale = hScale;
            h = vh;
            w = sw / scale;
        }

        return {
            scale: scale,
            w: w,
            h: h
        };
    };

    /* 更新裁剪预览图 */
    function _updatePreview(c) {
        var cropAreaImg = Crop.cropPreview.cropAreaImg;
        var cropPreviewImg = Crop.cropPreview.cropPreviewImg;
        var $cropObj = $.data(document.getElementById(Crop.crop.id), ‘crop‘).$cropObj;
        var $cropDataInp = $cropObj.$cropDataInp;
        var $cropPreview = $cropObj.$cropPreview;
        var $previewParent = $cropPreview.parent();
        var vw = $previewParent.width(), vh = $previewParent.height();
        var scaleOpt = _getScale(vw, vh, c.w, c.h);
        $cropPreview.width(scaleOpt.w);
        $cropPreview.height(scaleOpt.h);
        var width = $(cropAreaImg).width() / scaleOpt.scale;
        var height = $(cropAreaImg).height() / scaleOpt.scale;
        var top = -(c.y / scaleOpt.scale);
        var left = -(c.x / scaleOpt.scale);
        cropPreviewImg.style.width = width + ‘px‘;
        cropPreviewImg.style.height = height + ‘px‘;
        cropPreviewImg.style.top = top + ‘px‘;
        cropPreviewImg.style.left = left + ‘px‘;
        _setCropData($cropDataInp, c);
    };

    /* 设置裁剪数据 */
    function _setCropData($cropDataInp, c) {
        var ratio = Crop.ratio;
        var data = {
            x: c.x * ratio,
            y: c.y * ratio,
            w: c.w * ratio,
            h: c.h * ratio
        };

        var dataJson = JSON.stringify(data);
        $cropDataInp.val(dataJson);
    };

    /* 扩展配置参数,尤其是Jcrop裁剪参数中的onSelect,onChange参数 */
    function _extendOpt(opt) {
        opt = $.extend(true, {}, defaultOpt, opt);
        var select = opt.cropParam.onSelect;
        var change = opt.cropParam.onChange;
        if(Object.prototype.toString.call(select) == ‘[object Function]‘) {
            opt.cropParam.onSelect = function(c) {
                _updatePreview.call(jcropApi, c);
                select.call(jcropApi, c);
            };
        } else {
            opt.cropParam.onSelect = _updatePreview;
        }
        if(Object.prototype.toString.call(change) == ‘[object Function]‘) {
            opt.cropParam.onChange = function(c) {
                _updatePreview.call(jcropApi, c);
                change.call(jcropApi, c);
            }
        } else {
            opt.cropParam.onChange = _updatePreview;
        }
        return opt;
    };

    /* 初始化上传裁剪区域 */
    function init(opt) {
        var opt = _extendOpt(opt);
        var $uploadCropWrap = $(‘#‘ + opt.id);
        var hasDom = true;
        if($uploadCropWrap.length == 0) {
            $uploadCropWrap = $(‘<div id="‘ + opt.id + ‘" />‘);
            hasDom = false;
        }

        /* 清空Dom原有内部结构 */
        $uploadCropWrap.html(‘‘);
        var $cropObj = _createDom($uploadCropWrap, opt);

        $.data($uploadCropWrap.get(0), ‘crop‘, {opt: opt, $cropObj: $cropObj});
        hasDom || $(‘body‘).append($uploadCropWrap);

        _bind($cropObj, opt);

        Crop.crop = {id: opt.id, hasDom: hasDom};
    };

    /* 上传 */
    function upload() {
        var id = (Crop.crop && Crop.crop.id) || ‘‘;
        var dom = document.getElementById(id);
        if(!dom) {
            return ;
        }
        var form = $.data(dom, ‘crop‘).$cropObj.$form.get(0);
        form.submit();
    };

    /* 取消裁剪 */
    function cancel() {
        var id = (Crop.crop && Crop.crop.id) || "";
        var dom = document.getElementById(id);
        if(!dom) {
            return ;
        }
        var $cropObj = $.data(dom, ‘crop‘).$cropObj;
        $cropObj.$cropWrap.addClass(‘crop-hidden‘);
        $cropObj.$cropPicker.removeClass(‘crop-hidden‘);
    };

    /* 销毁上传裁剪区域 */
    function destroy() {
        var crop = Crop.crop || {};
        var $cropWrap = $(‘#‘ + crop.id);
        if(crop.hasDom === true) {
            $cropWrap.html(‘‘);
        } else {
            $cropWrap.remove();
        }
    };

    if($.isEmptyObject(Crop)) {
        global.Crop = Crop = {
            init: init,
            upload: upload,
            cancel: cancel,
            destroy: destroy,
            crop: {}
        };
    } else {
        Crop = $.extend(Crop, {
            init: init,
            upload: upload,
            cancel: cancel,
            destroy: destroy,
            crop: {}
        });
    }
})(window, jQuery, window.Crop || {});

前端就这两个是主要的文件,网上找不到的,其他的文件都是可以找到的,贴出来文件图

主要文件就两个,jquery.Jcrop.css,jquery.Jcrop.js

都可以找到自己去下载就可以。

 前端好了就是后台代码了,使用jfinal做的

工具类主要用到了裁剪和缩放

package cn.rjj.common.tools;

import java.awt.Rectangle;
import java.awt.image.BufferedImage;
import java.io.File;
import java.io.FileInputStream;
import java.io.FileNotFoundException;
import java.io.IOException;
import java.util.Iterator;

import javax.imageio.ImageIO;
import javax.imageio.ImageReadParam;
import javax.imageio.ImageReader;
import javax.imageio.stream.ImageInputStream;

public class ImageTool {

    /**
     * 对图片进行剪裁,只保存选中的区域
     *
     * @param img
     *            原图路径
     * @param dest
     *            目标路径
     * @param top
     *            裁剪图片的开始位置,距离顶部的高度
     * @param left
     *            裁剪图片的开始位置,距离左边部的距离
     * @param width
     *            目标图片的宽度
     * @param height
     *            目标图片高度
     * @param tw
     *            原图页面显示宽度
     * @param ty
     *            原图页面显示高度
     *
     * @return
     * @throws IOException
     */
    public static boolean saveImage(File img, String dest, int top, int left, int width, int height, int tw, int ty) {
        try {
            File fileDest = new File(dest);
            if (!fileDest.getParentFile().exists())
                fileDest.getParentFile().mkdirs();
            // 读取原图
            BufferedImage bfi = (BufferedImage) ImageIO.read(img);

            // 获得原图片的大小,并且按照前端页面中设置的图片的大小,缩放宽高
            BufferedImage bi = resizeImage(bfi, BufferedImage.TYPE_INT_ARGB, tw, ty);

            // 下边是裁剪,要裁剪的图片,目标宽高大于实际宽高就取实际宽高,小于,就拿到目标宽高
            height = Math.min(height, bi.getHeight());
            width = Math.min(width, bi.getWidth());
            // 如果截取的宽高小于等于0,那么就保留实际宽高
            if (height <= 0)
                height = bi.getHeight();
            if (width <= 0)
                width = bi.getWidth();
            top = Math.min(Math.max(0, top), bi.getHeight() - height);
            left = Math.min(Math.max(0, left), bi.getWidth() - width);

            // 截取图片,.getSubimage(left(左边位置), top(上边位置), width(要截图的宽),
            // height(要截取图片的高度));
            BufferedImage bi_cropper = bi.getSubimage(left, top, width, height);
            return ImageIO.write(bi_cropper, "jpeg", fileDest);
        } catch (IOException e) {
            e.printStackTrace();
        }
        return false;
    }

    /**
     * 缩小后的图片
     *
     * @author
     * @time 2018年8月3日下午9:13:23
     * @param originalImage
     * @param type
     * @param targetWidth
     * @param targetHeught
     * @return
     * @throws FileNotFoundException
     *             BufferedImage
     */
    private static BufferedImage resizeImage(BufferedImage originalImage, int type, int targetWidth, int targetHeught)
            throws FileNotFoundException {
        /*
         * 这个出来的像素很差,有兴趣的可以自己研究下 BufferedImage resizedImage = new
         * BufferedImage(IMG_WIDTH, IMG_HEIGHT, type); Graphics2D g =
         * resizedImage.createGraphics(); g.drawImage(originalImage, 0, 0,
         * IMG_WIDTH, IMG_HEIGHT, null); g.dispose();
         */

        // 构建图片流
        BufferedImage tag = new BufferedImage(targetWidth, targetHeught, BufferedImage.TYPE_INT_RGB);
        // 绘制改变尺寸后的图
        tag.getGraphics().drawImage(originalImage, 0, 0, targetWidth, targetHeught, null);

        // 输出流
        // 这里是测试,为了看下这个图片缩放后的样子
        /*
         * try { ImageIO.write(tag, "jpeg", new
         * FileOutputStream("E:/copy.jpg")); } catch (IOException e) { // TODO
         * Auto-generated catch block e.printStackTrace(); }
         */
        return tag;
    }

    /**
     * 对图片裁剪,并把裁剪新图片保存
     *
     * @param srcPath
     *            读取源图片路径
     * @param toPath
     *            写入图片路径
     * @param x
     *            剪切起始点x坐标
     * @param y
     *            剪切起始点y坐标
     * @param width
     *            剪切宽度
     * @param height
     *            剪切高度
     * @param readImageFormat
     *            读取图片格式
     * @param writeImageFormat
     *            写入图片格式
     * @return
     * @throws IOException
     */
    public boolean cropImage(String srcPath, String toPath, int x, int y, int width, int height, String readImageFormat,
            String writeImageFormat) {
        try {
            FileInputStream fis = null;
            ImageInputStream iis = null;
            try {
                // 读取图片文件
                fis = new FileInputStream(srcPath);
                Iterator<?> it = ImageIO.getImageReadersByFormatName(readImageFormat);
                ImageReader reader = (ImageReader) it.next();
                // 获取图片流
                iis = ImageIO.createImageInputStream(fis);
                reader.setInput(iis, true);
                ImageReadParam param = reader.getDefaultReadParam();
                // 定义一个矩形
                Rectangle rect = new Rectangle(x, y, width, height);
                // 提供一个 BufferedImage,将其用作解码像素数据的目标。
                param.setSourceRegion(rect);
                BufferedImage bi = reader.read(0, param);
                // 保存新图片
                ImageIO.write(bi, writeImageFormat, new File(toPath));
                return true;
            } finally {
                if (fis != null)
                    fis.close();
                if (iis != null)
                    iis.close();
            }
        } catch (FileNotFoundException e) {
            e.printStackTrace();
            return false;
        } catch (IOException e) {
            e.printStackTrace();
            return false;
        }
    }
}
最后就是主要代码,controller中的操作。这里只是上传的操作做了,可以根据自己的业务,把图片保存的时候把路径保留到,使得图片路径和用户关联,这样显示用户头像的时候,直接拿到路径,就可以显示图片了

package cn.rjj.common.upload;

import java.io.File;
import java.util.Date;
import java.util.List;

import com.alibaba.fastjson.JSONObject;
import com.jfinal.core.Controller;
import com.jfinal.kit.PathKit;
import com.jfinal.upload.UploadFile;

import cn.rjj.common.tools.ImageTool;
/**
 *
 * @author
 * url:/upload
 */
public class UploadHeardPicture extends Controller {

    public void index(){
        redirect("/upload/toUploadHeadPicture");
    }

    /**
     * 上传头像页面
     * url:/upload/toUploadHeadPicture
     */
    public void toUploadHeadPicture(){
        render("headUpload.html");
    }

    /**
     * 头像上传
     * url:/upload/uploadHeaderPic
     *
     * 先把图片上传到服务其上,根据参数进行裁剪,然后把原来的那张图片删除,就可以了。把资源也省下来了
     */
    public void uploadHeaderPic() {

        File file = new File("/upload/head");
        if(!file.exists()){
            file.mkdirs();
        }
        //设置图片上传位置
        List<UploadFile> files =  getFiles("head");
        //获得参数
        int left= (int) Math.round(Double.parseDouble(getPara("x11")));
        int top= (int) Math.round(Double.parseDouble(getPara("y11")));
        int width= (int) Math.round(Double.parseDouble(getPara("w"))) ;
        int height= (int) Math.round(Double.parseDouble(getPara("h"))) ;
        String para = getPara("tw");
        String para2 = getPara("ty");
        String substring = para.substring(0,para.length()-2);
        int tw= (int) Math.round(Double.parseDouble(substring)) ;
        String substring2 = para2.substring(0,para2.length()-2);
        int ty= (int) Math.round(Double.parseDouble(substring2)) ;

        JSONObject json= new JSONObject();
        UploadFile uploadFile = getFile("img0");
        //for (UploadFile uploadFile : files) {
        File source = uploadFile.getFile();
        String fileName = source.getName();
       // boolean isSave = cropImage(source.getPath(),PathKit.getWebRootPath()+"/upload/head/" + new Date().getTime()+fileName,top,left,width,height,"jpg","jpg");
        //这个是对图片进行缩放后在裁剪的
        boolean isSave = ImageTool.saveImage(source,PathKit.getWebRootPath()+"/upload/head/" + new Date().getTime()+fileName,top,left,width,height,tw,ty);
        //删除原来的图片,
        source.delete();
        if(isSave){
            json.put("msg", "头像更新成功!");
        }else{
            json.put("msg", "头像更新失败!");
        }
       // }
        renderJson(json);
    }

}

我把完整项目放到https://download.csdn.net/download/qq_20359393/10584618

可以去下载实验效果。项目可以再次优化。目前只是实现了需要的功能。

原文地址:https://www.cnblogs.com/renjianjun/p/9426048.html

时间: 2024-10-12 17:44:30

jfinal头像裁剪上传服务器的相关文章

html5 canvas头像裁剪上传

效果: 在博客里有另一篇头像裁剪是用actionscript实现的头像裁剪上传,这里拥护html5,用canvas实现下.前两次的右键是为了说明不是用flash做的. 如果想要更严谨的,有技术支持的这个东西的话,可以用kissy的http://gallery.kissyui.com/imgcrop/2.0/guide/index.html. 原理很简单:裁剪框是用html做的,canvas的作用在于每次移动,变形后根据裁剪框的位置坐标以及大小,绘制图像的部分并缩放,还有绘制裁剪框区域外的灰色区域

springMVC 头像裁剪上传并等比压

第一次写头像裁剪上传,原本想着直接本地预览裁剪再上传,可是时间有限,jquery.jcrop貌似并没有对 假设是ie下图片预览效果是滤镜做的  做出对应处理,也没有时间去改;仅仅好将就一下先把图片上传上去再预览 1.先看一下我引入的js <script src="${adminBasePath}resources/js/jquery.1.8.3.js"></script> <script src="${adminBasePath}resource

java头像裁剪上传

原文:java头像裁剪上传 源代码下载地址:http://www.zuidaima.com/share/1550463771118592.htm jsp页面实现头像裁剪上传,带进度条,后台java接收 上传成功后

基于cropper和sweetalert的简单图片/头像裁剪上传

基本功能 前端基本样式: 进行图片裁剪及上传: 点击上传后,js会将截取到的数据转为图片数据利用ajax发送给后台进行存储.存储成功后,刷新前端页面,头像改变. 上传成功后:自动刷新网页,更改头像 基本工具 cropper是一个功能强大的jq插件,在指定图片img上添加裁剪框,并根据指定事件对图片按照裁剪框的大小进行裁剪. crepper还可以对定义图片翻转.放大.移动以及输出裁剪框位置的很多功能,由于此处只是用于头像上传,所以只使用了基本功能. cropper使用时需要用到jq2.0以上,所以

Android之修改用户头像并上传服务器(实现手机拍照和SD卡选择上传)

写了这么多个的APP,最近才把他这个功能写上来,就抽取其中的用户修改头像的相关操作这个功能写了这篇博客,来与大家分享,希望对你有所帮助. 案例包含了: Xutil图片上传 拍照和SD卡选择图片 图片缓存和界面逻辑处理 图片压缩和图片处理 自定义圆形头像 XUtils.Jar 下载 其他图片上传方式请看博客  :Volley-XUtils-OkHttp三种方式实现单张多张图片上传 效果图:(注:模拟器没拍照功能,效果图只有SD卡上传,手机测试拍照上传也是可以的) 代码: MainActivity.

超少代码的头像裁剪上传

效果: as上传的好处在于裁剪工作在客户端就完成了,而用jcrop的话要记录裁剪大小,位置坐标等,传给服务端才能裁剪 代码很简单 1 package 2 { 3 import flash.display.*; 4 import flash.events.Event; 5 import flash.utils.ByteArray; 6 import flash.events.*; 7 import flash.net.*; 8 import com.adobe.images.JPGEncoder;

小议头像预览裁剪上传的实现

在做头像上传的时候,浏览器默认是无法取得本地图片的,当然 HTML5 是可以的.不过IE6-8怎么破?目前比较通用的方案都是 flash 解决. 说道头像预览和裁剪,我最熟悉的就是 Discuz 的那个了,非常方便好用.不仅可以选择本地图片,还能直接调用摄像头拍摄,当然前提是你必须有个摄像头. 于是我心血来潮的想把他剥离出来给项目用,于是有就了此文..我就不说怎么提取怎么调用,就简单的谈谈他是怎么处理图片好了,反正不是我们想的那样,和我想的出入非常大. 这个插件呢,差不多分为四步处理:1. 前台

前端插件——头像截图上传插件的使用(带后台)

效果图:实现上传头像,右边是预览,有三个大小,可以对头像进行裁剪 HTML: toParentData 和 img 返回的是图片裁剪后的base64编码.其中toParentData用于业务需求,可以忽略. <!DOCTYPE html> <%@ taglib prefix="c" uri="http://java.sun.com/jsp/jstl/core" %> <html> <head> <c:set va

图片裁剪上传Jcrop

<link rel="stylesheet" href="../css/jquery.Jcrop.css"> <script src="../js/jquery.Jcrop.js"></script> 先是两个必不可少的东西 <style type="text/css"> /* Apply these styles only when #preview-pane has been