• 修改头像总结


    1,背景
    博客停了好久,主要是最近工作太忙了,还有就是身体状况没有以前那么好了,乘着国庆长假的空档,写下这篇一直想写的文章。
    运营平台是我主要致力的一个项目,这个项目分为四个大部分,个人中心,充值中心,客服中心,家长监护,最近主要忙着个人中心的重写和丰富,关于个人中心,无非就是对平台用户信息的自我管理,以及一些对用户帐号的安全保护措施,下图的菜单非常简要的说明了个人中心的功能。个人觉得最值得关注的就是密保设置和修改头像,因为之前没有处理过类似的问题,本文主要记录对头像的处理过程以及思考,希望给碰到类似问题的苦逼程序员一点借鉴。
    个人中心整体功能一览

    2,头像处理xmind
    叽歪一句,个人碰到问题的时候,首先会分析问题,在分析问题的基础上,得到整体的解决方案,然后一步步分解步骤,去实现,首先奉上我的解决方案,也许不是最优的,但是按照个人的知识和技能水平,绝对是可以实现的。


                     修改头像mind

    3,实现步骤
    按照我的mind,首先是上传图片,先上效果图,然后给出实现的代码。首先是整体的结构图,做的比较丑,别喷哥···

     修改头像整体效果图
    下面按照mind一步步实现,
    首先:点击修改头像,弹出一个层,

    第一步:弹出上传图片的层,上传图片到服务器
      对实现细节不感冒的屌丝可以看看代码(结合哥的mind看可以事半功倍):
    分层 实现细节
    Html结构层 这个可以免了,一般都可以弄出来
    Js连接层
    首先是弹出一个上传图片的层,然后上传图片到服务器端。 $("#editHead").bind("click", function () {
            showUploadDiv();
        });
        function showUploadDiv() {
            $("#uploadMsg").empty();
            $.fancybox({
                type:'inline',
                400,
                href:'#uploadUserHead'
            });
    }//fancybox弹出层
    上传的处理代码
    Servlet服务端处理层(commonupload实现) 服务器端处理代码

    上传的处理代码
     $(function () {
            $("#uploadFrom").ajaxForm({
                beforeSubmit:checkImg,
                error:function(data,status){
                    alert(status+' , '+data);
                    $("#uploadMsg").html('上传文件超过1M!');
                },
                success:function (data,status) {
                  try{
                      var msg = $.parseJSON(data);
                      if (msg.code == 200)
                      { //如果成功提交
                          javascript:$.fancybox.close();
                          $("#uploadUserHead").hide();
                          var data = msg.object;
                          $("#editImg").attr("src", data.path).show();
                          $("#preview1").attr("src", data.path).show();
                          $(".zoom").show();
                          $("#width").val(data.width);
                          $("#height").val(data.height);
                          $("#oldImgPath").val(data.realPath);
                          $("#imgFileExt").val(data.fileExt);
                          var api, jcrop_api, boundx, boundy;
                          $('#editImg').Jcrop({
                              onChange:updatePreview,
                              onSelect:updatePreview,
                              aspectRatio:1,
                              bgOpacity:0.5,
                              bgColor:'white',
                              addClass:'jcrop-light'
                          }, function () {
                              api = this;
                              api.setSelect([130, 65, 130 + 350, 65 + 285]);
                              api.setOptions({ bgFade:true });
                              api.ui.selection.addClass('jcrop-selection');
                              var bounds = this.getBounds();
                              boundx = bounds[0];
                              boundy = bounds[1];
                              jcrop_api = this;
                          });
                          function updatePreview(c) {
                              if (parseInt(c.w) > 0) {
                                  var rx = 80 / c.w;
                                  var ry = 80 / c.h;
                                  $('#preview1').css({
                                      Math.round(rx * boundx) + 'px',
                                      height:Math.round(ry * boundy) + 'px',
                                      marginLeft:'-' + Math.round(rx * c.x) + 'px',
                                      marginTop:'-' + Math.round(ry * c.y) + 'px'
                                  });
                              }
                              jQuery('#x').val(c.x);
                              jQuery('#y').val(c.y);
                              jQuery('#x2').val(c.x2);
                              jQuery('#y2').val(c.y2);
                              jQuery('#w').val(c.w);
                              jQuery('#h').val(c.h);
                          }
                      }
                      if (msg.code == 204) {
                          $("#uploadMsg").html(msg.msg);
                      }
                  }catch (e){
                      $("#uploadMsg").html('上传文件超过1M!');
                  }

                }
            });
        });
    //服务器端处理代码
     String tempSavePath =  ConfigurationUtils.get("user.resource.dir"); //上传的图片零时保存路径
             String tempShowPath =  ConfigurationUtils.get("user.resource.url"); //用户保存的头像路径

            if(tempSavePath.equals("/img"))
            {
                 tempSavePath=sc.getRealPath("/")+tempSavePath;
            }
            Msg msg = new Msg();
            msg.setCode(204);
            msg.setMsg("上传头像失败!");
            String type = request.getParameter("type");
            if (!Strings.isNullOrEmpty(type) && type.equals("first")) {
                request.setCharacterEncoding("utf-8");
                DiskFileItemFactory factory = new DiskFileItemFactory();
                ServletFileUpload servletFileUpload = new ServletFileUpload(factory);
                try {
                    List items = servletFileUpload.parseRequest(request);
                    Iterator iterator = items.iterator();
                    while (iterator.hasNext()) {
                        FileItem item = (FileItem) iterator.next();
                        if (!item.isFormField()) {
                            {
                                File tempFile = new File(item.getName());
                                File saveTemp = new File(tempSavePath+"/tempImg/");
                                String getItemName=tempFile.getName();
                                String fileName = UUID.randomUUID()+"." +getItemName.substring(getItemName.lastIndexOf(".") + 1, getItemName.length());
                                File saveDir = new File(tempSavePath+"/tempImg/", fileName);
                                //如果目录不存在,创建。
                                if (saveTemp.exists() == false) {
                                    if (!saveTemp.mkdir()) { // 创建失败
                                        saveTemp.getParentFile().mkdir();
                                        saveTemp.mkdir();
                                    } else {
                                    }
                                }
                                if (saveDir.exists()) {
                                    log.info("存在同名文件···");
                                    saveDir.delete();
                                }
                                item.write(saveDir);
                                log.info("上传头像成功!"+saveDir.getName());

                                msg.setCode(200);
                                msg.setMsg("上传头像成功!");

                                Image image = new Image();
                                BufferedImage bufferedImage = null;
                                try {
                                    bufferedImage = ImageIO.read(saveDir);
                                } catch (IOException e) {
                                    e.printStackTrace();
                                }
                                image.setHeight(bufferedImage.getHeight());
                                image.setWidth(bufferedImage.getWidth());
                                image.setPath(tempShowPath+ "/tempImg/" + fileName);
                                log.info(image.getPath());
                                image.setRealPath(tempSavePath+"/tempImg/"+ fileName);
                                image.setFileExt(fileName.substring(fileName.lastIndexOf(".") + 1, fileName.length()));
                                msg.setObject(image);
                            }
                        } else {
                            log.info("" + item.getFieldName());
                        }
                    }
                } catch (Exception ex) {
                    log.error("上传用户头像图片异常!");
                    ex.printStackTrace();
                }
                finally {
                    AppHelper.returnJsonAjaxForm(response, msg);
                }
            }
    上传成功后,可以看到照片和照片的预览效果。看图:


    上传头像之后的效果

    Friday, October 05, 2012
    第二步:编辑和保存头像
    选中图中的区域,保存头像,就完成头像的修改。
    修改之后的效果入下:

    修改之后的头像(因为传了一张动态图片,得到的跟上图有些不同)

    实现细节:
    首先用了一个js控件:Jcrop,有兴趣的屌丝可以去搜一下,然后,利用上传之后的图片和之前的选定区域,完成了一个截图,保存为用户的头像。

    连接层的js:
     $("#saveHead").bind("click", function () {
            var width = $("#width").val();
            var height = $("#height").val();
            var oldImgPath = $("#oldImgPath").val();
            var imgFileExt = $("#imgFileExt").val();
            var x = $('#x').val();
            var y = $('#y').val();
            var w = $('#w').val();
            var h = $('#h').val();

            $.ajax({
                url:'/imgCrop',
                type:'post',
                data:{x:x, y:y, w:w, h:h, width, height:height, oldImgPath:oldImgPath, fileExt:imgFileExt},
                datatype:'json',
                success:function (msg) {
                    if (msg.code == 200) {
                        $("#avatar").attr("src", msg.object);
                        forword('/nav', 'index');
                    }
                    else {
                        alert(msg.msg);
                    }
                }
            });
        });
        function checkImg() {
            //限制上传文件的大小和后缀名
            var filePath = $("input[name='uploadImg']").val();
            if (!filePath) {
                $("#uploadMsg").html("请选择上传文件!").show();
                return false;
            }
            else {
                var extStart = filePath.lastIndexOf(".");
                var ext = filePath.substring(extStart, filePath.length).toUpperCase();
                if (ext != ".PNG" && ext != ".GIF" && ext != ".JPG") {
                    $("#uploadMsg").html("图片限于png,gif,jpg格式!").show();
                    return false;
                }
            }
            return true;
    }
    服务器端处理代码:
    String savePath =  ConfigurationUtils.get("user.resource.dir"); //上传的图片保存路径
           String showPath =  ConfigurationUtils.get("user.resource.url"); //显示图片的路径
           if(savePath.equals("/img"))
           {
               savePath=sc.getRealPath("/")+savePath;
           }
           int userId = AppHelper.getUserId(request);
           String userName=AppHelper.getUserName(request);
           Msg msg = new Msg();
           msg.setCode(204);
           msg.setMsg("剪切图片失败!");
           if (userId <= 0) {
               msg.setMsg("请先登录");
               return;
           }
           // 用户经过剪辑后的图片的大小
           Integer x = (int)Float.parseFloat(request.getParameter("x"));
           Integer y = (int)Float.parseFloat(request.getParameter("y"));
           Integer w = (int)Float.parseFloat(request.getParameter("w"));
           Integer h = (int)Float.parseFloat(request.getParameter("h"));
           //获取原显示图片路径 和大小
           String oldImgPath = request.getParameter("oldImgPath");
           Integer width = (int)Float.parseFloat(request.getParameter("width"));
           Integer height = (int)Float.parseFloat(request.getParameter("height"));
           //图片后缀
           String imgFileExt = request.getParameter("fileExt");
           String foldName="/"+ DateUtils.nowDatetoStrToMonth()+"/";
           String imgName = foldName + UUID.randomUUID()+userName + "." + imgFileExt;
           //组装图片真实名称
           String createImgPath = savePath + imgName;
           //进行剪切图片操作
           ImageCut.abscut(oldImgPath,createImgPath, x*width/300, y*height/300, w*width/300, h*height/300);
           File f = new File(createImgPath);
           if (f.exists()) {
               msg.setObject(imgName);
               //把显示路径保存到用户信息下面。
               UserService userService = userServiceProvider.get();
               int rel = userService.updateUserAvatar(userId, showPath+imgName);
               if (rel >= 1) {
                   msg.setCode(200);
                   msg.setMsg("剪切图片成功!");
                   log.info("剪切图片成功!");
                   //记录日志,更新session
                   log(showPath+imgName,userName);
                   UserObject userObject= userService.getUserObject(userName);
                   request.getSession().setAttribute("userObject", userObject);
                   if (userObject != null && Strings.isNullOrEmpty(userObject.getHeadDir()))
                       userObject.setHeadDir("/images/geren_right_01.jpg");
               } else {
                   msg.setCode(204);
                   msg.setMsg("剪切图片失败!");
                   log.info("剪切图片失败!");
               }
           }
           AppHelper.returnJson(response, msg);
           File file=new File(oldImgPath);
           boolean deleteFile= file.delete();
           if(deleteFile==true)
           {
               log.info("删除原来图片成功");
           }
    /**
        * 图像切割(改)     *
        *
        * @param srcImageFile 源图像地址
        * @param dirImageFile 新图像地址
        * @param x            目标切片起点x坐标
        * @param y            目标切片起点y坐标
        * @param destWidth    目标切片宽度
        * @param destHeight   目标切片高度
        */
       public static void abscut(String srcImageFile, String dirImageFile, int x, int y, int destWidth, int destHeight) {
           try {
               Image img;
               ImageFilter cropFilter;
               // 读取源图像
               BufferedImage bi = ImageIO.read(new File(srcImageFile));
               int srcWidth = bi.getWidth(); // 源图宽度
               int srcHeight = bi.getHeight(); // 源图高度
               if (srcWidth >= destWidth && srcHeight >= destHeight) {
                   Image image = bi.getScaledInstance(srcWidth, srcHeight, Image.SCALE_DEFAULT);
                   // 改进的想法:是否可用多线程加快切割速度
                   // 四个参数分别为图像起点坐标和宽高
                   // 即: CropImageFilter(int x,int y,int width,int height)
                   cropFilter = new CropImageFilter(x, y, destWidth, destHeight);
                   img = Toolkit.getDefaultToolkit().createImage(new FilteredImageSource(image.getSource(), cropFilter));
                   BufferedImage tag = new BufferedImage(destWidth, destHeight, BufferedImage.TYPE_INT_RGB);
                   Graphics g = tag.getGraphics();
                   g.drawImage(img, 0, 0, null); // 绘制缩小后的图
                   g.dispose();
                   // 输出为文件
                   ImageIO.write(tag, "JPEG", new File(dirImageFile));
               }
           } catch (Exception e) {
               e.printStackTrace();
           }
       }
    最后一个处理的比较好的地方就是图片的存储路径问题:
    我在服务器端的nginx中做了一个图片的地址映射,把图片放到了跟程序不同的路径中,每次存储图片都是存到图片路径中,客户端拿到图片的地址确实经过nginx映射过的地址。
    还有就是关于限制上传图片的大小的问题:
    我在服务器端显示了资源的最大大小为1M,当上传的资源超过1M,服务器自动报错413,通过异常处理,可以在客户端得到正确的提示信息。

    4,总结优点和不足。
       关于修改头像,这么做下来确实达到了目的,用户可以从容的修改头像,性能也还可以。但是,上传图片的大小判断是依靠服务器端来判断的,等待的时间比较久,改进的方向是使用flash控件来限制,使用flash来上传,也不会出现弹出层,这样比较大众化,更容易为用户接受一点。我会不断改进。
    no pays,no gains!
  • 相关阅读:
    ulimit -a
    nginx check_http_send type=http 查检测不到后端TOM的存活
    通过ip查找能应机器的MAC
    错误状态码URL重定向
    error_page 改变状态码为新的状态码,并显示指定内容
    使用 CefSharp 在 C# App 中嵌入 Chrome 浏览器
    C#客户端嵌入Chrome浏览器的实现
    Task.Run c#启动线程
    C#利用webBrowser怎么去掉网页中不想显示的部分
    InDesign CC 2019安装包+破解
  • 原文地址:https://www.cnblogs.com/snidget/p/2712109.html
Copyright © 2020-2023  润新知